<?php
/*! \brief
 * This is abstract class of WFWidgetPoolManager class
 * This is the Class that manipulate WidgetPool event
 * \author William Su
 */
abstract class AWidgetPoolManager
{
    protected $log_id;
    /**
     * @var WF
     */
    protected $objFramework;
    /**
     * @var WFWidgetPoolFactory
     */
    protected $objWidgetPoolFactory;
    /**
     * @var WFLogger
     */
    protected $objLogger;
    /**
     * @var WFConfig
     */
    protected $objConfig;
    /**
     * @var WFWidgetsNewInfoXmlManager
     */
    protected $objWidgetsNewInfoXmlManager;
    /**
     * @var WFWidgetComponentInfoXmlManager
     */
    protected $objWidgetComponentInfoXmlManager;
    /**
     * @var WFWidgetInfoXmlManager
     */
    protected $objWidgetInfoXmlManager;
    /**
     * @var string $strUpdateType There are 3 update types=>widget, configure_widget, widget_component
     */
    protected $strUpdateType;
    
    
    public function __construct($objFramework,$strUpdateType){
        $this->objFramework = $objFramework;
        $this->objWidgetPoolFactory = $this->objFramework->getWidgetPoolFactory($objFramework);
        $this->strWPRoot = $this->objWidgetPoolFactory->getWFHome() . '/repository/widgetPool';
        $this->objLogger = $this->objWidgetPoolFactory->getLogger();
        $this->objConfig = $this->objFramework->getConfigFactory()->getConfig();
        $this->objWidgetInfoXmlManager = $this->objWidgetPoolFactory->getWidgetInfoXmlManager();
        $this->objWidgetComponentInfoXmlManager = $this->objWidgetPoolFactory->getWidgetComponentInfoXmlManager();
        $this->objWidgetsNewInfoXmlManager = $this->objWidgetPoolFactory->getWidgetsNewInfoXmlManager();
        $this->strUpdateType = $strUpdateType;
        if(! class_exists('WFWidgetPoolOpt')){
            // include WFWidgetPoolOpt
            $this->objWidgetPoolFactory->getWidgetPoolOpt();
        }
    }
    /**
     *\brief Description
     * - Get PATH of current WidgetFramework
     * - EX : /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src
     * @return string
     */
    public function getWPHome(){
        $ret = $this->objWidgetPoolFactory->getWPHome();
        return $ret;
    }
    /**
     *\brief Description
     * - Setter of WFConfig, for UT injection
     */
    public function setObjConfig($objConfig){
        $this->objConfig = $objConfig;
    }
    /**
     *\brief Description
     * - Setter of WFWidgetsNewInfoXmlManager, for UT injection
     */
    public function setObjWidgetsNewInfoXmlManager($objWidgetsNewInfoXmlManager){
        $this->objWidgetsNewInfoXmlManager = $objWidgetsNewInfoXmlManager;
    }
    /**
     *\brief Description
     * - Get PATH of current WidgetPool Root
     * - EX : /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool
     * @var $strWPRoot string
     */
    private $strWPRoot;
    /**
     *\brief Description
     * - setter of $strWPRoot
     */
    public function setWPRoot($strWPRoot){
        $this->strWPRoot = $strWPRoot;
    }
    /************************************************
     * WIDGET,WIDGET_CATEGORY,WIDGET_CATEGORY_MAPPING Relative API @START
     ***********************************************/
    /**
     *\brief Description
     * - This method will get $arrDataWidget by widget_name
     *\par Variable
     * - EX: $strWidgetName
     * modFlickr
     * 
     * - EX: $arrDataWidget
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif'
     * )
     * @param string $strWidgetName
     * @return array $arrDataWidget
     */
    public function getArrDataWidgetByWidgetName($strWidgetName){
        $arrDataXML = $this->getArrDataWidgetXMLByCondition($strWidgetName);
        $ret = $this->getArrDataWidgetByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidget by PATH of widget
     *\par Variable
     * - EX: $strPathWidget
     * /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool/wpLogId/modFlickr
     * 
     * - EX: $arrDataWidget
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif'
     * )
     * @param string $strWidgetName
     * @return array $arrDataWidget
     */
    public function getArrDataWidgetByWidgetPath($strPathWidget){
        if(false === strpos($strPathWidget, 'widget.xml')){ //if not found widget.xml in $strPathWidget
            $strPathWidgetXml = $strPathWidget . '/widget.xml';
        }else{
            $strPathWidgetXml = $strPathWidget;
        }
        $arrDataXML = $this->objWidgetPoolFactory->getSimplexml($strPathWidgetXml)->toArray();
        $ret = $this->getArrDataWidgetByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidget by $strDom
     *\par Variable
     * - EX: $strDom
     * <?xml version="1.0" encoding="UTF-8"?>
     * <widget>
     * <widget_name>modFlickr</widget_name>
     * <widget_version>1.0</widget_version>
     * <categories>
     * <category>
     * <category_name>WidgetFramework</category_name>
     * <min_support_version>1.5</min_support_version>
     * </category>
     * </categories>
     * <widget_status>1</widget_status>
     * <widget_min_wf_version>2.0</widget_min_wf_version>
     * <user_generated>0</user_generated>
     * <icon>wicon_table.gif</icon>
     * </widget>
     * 
     * - EX: $arrDataWidget
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif'
     * )
     * @param string $strDom
     * @return array $arrDataWidget
     */
    public function getArrDataWidgetByDom($strDom){
        $arrDataXML = $this->getArrDataWidgetXMLByCondition(null, $strDom);
        $ret = $this->getArrDataWidgetByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidget from $arrDataXML
     *\par Variable
     * - EX : $arrDataXML:
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5',
     * ),
     * ),
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif'
     * )
     * - EX: $arrDataWidget
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif'
     * )
     * @param array $arrDataXML
     * @return array $arrDataWidget
     */
    protected function getArrDataWidgetByArrDataXML($arrDataXML){
        $arrData = array();
        unset($arrDataXML['categories']);
        return $arrDataXML;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidget from $arrDataXML
     *\par Variable
     * - EX : $arrData:
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5',
     * ),
     * ),
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif'
     * )
     * @param array $arrDataXML
     * @return array $arrDataWidget
     */
    public function getArrDataByWidgetName($strWidgetName){
        $arrData = $this->getArrDataWidgetXMLByCondition($strWidgetName);
        return $arrData;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetCategory by $strWidgetName
     *\par Variable
     * - EX : $strWidgetName
     * modFlickr
     * 
     * - EX : $arrsDataWidgetCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5'
     * )
     * )
     * @param string $strWidgetName
     * @return array $arrsDataWidgetCategory
     */
    public function getArrsDataWidgetCategoryByWidgetName($strWidgetName){
        $arrDataXML = $this->getArrDataWidgetXMLByCondition($strWidgetName);
        $ret = $this->getArrsDataWidgetCategoryByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetCategory by $strPathWidget
     *\par Variable
     * - EX : $strPathWidget
     * /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool/wpLogId/modFlickr
     * 
     * - EX : $arrsDataWidgetCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5'
     * )
     * )
     * @param string $strPathWidget
     * @return array $arrsDataWidgetCategory
     */
    public function getArrsDataWidgetCategoryByWidgetPath($strPathWidget){
        $strPathWidgetXml = $strPathWidget . '/widget.xml';
        $arrDataXML = $this->objWidgetPoolFactory->getSimplexml($strPathWidgetXml)->toArray();
        $ret = $this->getArrsDataWidgetCategoryByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetCategory by $strDom
     *\par Variable
     * - EX: $strDom
     * <?xml version="1.0" encoding="UTF-8"?>
     * <widget>
     * <widget_name>modFlickr</widget_name>
     * <widget_version>1.0</widget_version>
     * <categories>
     * <category>
     * <category_name>WidgetFramework</category_name>
     * <min_support_version>1.5</min_support_version>
     * </category>
     * </categories>
     * <widget_status>1</widget_status>
     * <widget_min_wf_version>2.0</widget_min_wf_version>
     * <user_generated>0</user_generated>
     * <icon>wicon_table.gif</icon>
     * </widget>
     * 
     * - EX : $arrsDataWidgetCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5'
     * )
     * )
     * @param string $strDom
     * @return array $arrsDataWidgetCategory
     */
    public function getArrsDataWidgetCategoryByDom($strDom){
        $arrDataXML = $this->getArrDataWidgetXMLByCondition(null, $strDom);
        $ret = $this->getArrsDataWidgetCategoryByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetCategory by $arrDataXML
     *\par Variable
     * - EX: $arrDataXML
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5',
     * ),
     * ),
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif',
     * )
     * 
     * - EX : $arrsDataWidgetCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5'
     * )
     * )
     * @param array $arrDataXML
     * @return array $arrsDataWidgetCategory
     */
    protected function getArrsDataWidgetCategoryByArrDataXML($arrDataXML){
        $ret = array();
        //$arrDataXML['categories']['category'];
        if(! isset($arrDataXML['categories']['category'][0])){ //the category is only one
            $ret[0] = $arrDataXML['categories']['category'];
        }else{
            $ret = $arrDataXML['categories']['category'];
        }
        return $ret;
    }
    /**
     *\brief Description
     * - You can get a $objSimplexml either from $strWidgetName or $strDom,
     * - This method will return the $arrDataWidgetXML by call $objSimplexml->toArray()
     *\par Variable
     * - EX: $strWidgetName
     * modFlickr
     * 
     * - EX: $strDom
     * <?xml version="1.0" encoding="UTF-8"?>
     * <widget>
     * <widget_name>modFlickr</widget_name>
     * <widget_version>1.0</widget_version>
     * <categories>
     * <category>
     * <category_name>WidgetFramework</category_name>
     * <min_support_version>1.5</min_support_version>
     * </category>
     * </categories>
     * <widget_status>1</widget_status>
     * <widget_min_wf_version>2.0</widget_min_wf_version>
     * <user_generated>0</user_generated>
     * <icon>wicon_table.gif</icon>
     * <widget_key></widget_key>
     * <param></param>
     * </widget>
     * 
     * - EX: $arrDataXML
     * array (
     * 'widget_name' => 'modFlickr',
     * 'widget_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'WidgetFramework',
     * 'min_support_version' => '1.5',
     * ),
     * ),
     * 'widget_status' => '1',
     * 'widget_min_wf_version' => '2.0',
     * 'user_generated' => NULL,
     * 'icon' => 'wicon_table.gif',
     * )
     * 
     * @param string $strWidgetName 
     * @param string $strDom
     * @return array $arrDataWidgetXML
     */
    protected function getArrDataWidgetXMLByCondition($strWidgetName = null, $strDom = null){
        if(null !== $strWidgetName){
            $strPathWidgetRoot = $this->getWPHome() . '/widget';
            $strModXmlPathWidgetPool = $strPathWidgetRoot . '/' . $strWidgetName . '/widget.xml';
            $strPathWidgetRoot = $this->objFramework->getDocumentRoot() . '/repository/userGenerated/widget';
            $strModXmlPathUserGenerated = $strPathWidgetRoot . '/' . $strWidgetName . '/widget.xml';
            if(true === file_exists($strModXmlPathWidgetPool)){
                $objSimplexml = $this->objWidgetPoolFactory->getSimplexml($strModXmlPathWidgetPool);
            }elseif(true === file_exists($strModXmlPathUserGenerated)){
                $objSimplexml = $this->objWidgetPoolFactory->getSimplexml($strModXmlPathUserGenerated);
            }else{
                throw new WFWidgetPoolWidgetPoolManagerException("widget.xml of " . $strWidgetName . " is required!");
            }
        }else{
            $objSimplexml = $this->objWidgetPoolFactory->getSimplexml($strDom);
        }
        return $objSimplexml->toArray();
    }
    /************************************************
     * WIDGET,WIDGET_CATEGORY,WIDGET_CATEGORY_MAPPING Relative API @END
     ***********************************************/
    /**
     *\brief Description 
     * This method will check is folder /path/to/src/widgets_new exist?
     */
    protected function isFolderWidgetsNewExist(){
        $strPath = $this->getPathWidgetsNewRelativePath();
        $ret = file_exists($strPath) ? true : false;
        if(false === $ret){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>folder /path/to/src/widgets_new does not exist!';
            throw new WFWidgetPoolWidgetPoolManagerException($message);
        }
        return $ret;
    }
    /**
     *\brief Description 
     * This method will check is folder /path/to/src/widgets_new is_writable?
     */
    protected function isFolderWidgetsNewWritable(){
        $strPath = $this->getPathWidgetsNewRelativePath();
        $this->objFramework->getIOFactory()->getFile()->isWritableRecursive($strPath);
    }
    /**
     *\brief Description 
     * This method will check is folder /path/to/src/widgets_new is_readable?
     */
    protected function isFolderWidgetsNewReadable(){
        $strPath = $this->getPathWidgetsNewRelativePath();
        $this->objFramework->getIOFactory()->getFile()->isReadableRecursive($strPath);
    }
    /**
     *\brief Description 
     * This method will check is folder /path/to/src/repository/widgetPool is_writable?
     */
    protected function isFolderWidgetPoolWritable(){
        $strPath = $this->getDocumentRootRelativePath() . '/repository/widgetPool';
        $this->objFramework->getIOFactory()->getFile()->isWritableRecursive($strPath);
    }
    /**
     *\brief Description 
     * This method will check is folder /path/to/src/repository/widgetPool is_writable?
     */
    protected function isFolderWidgetPoolReadable(){
        $strPath = $this->getDocumentRootRelativePath() . '/repository/widgetPool';
        $this->objFramework->getIOFactory()->getFile()->isReadableRecursive($strPath);
    }
    /**
     *\brief Description 
     * - This method will check the length of path to copy is too long or not?
     * - Maximun path length is 255
     * - Logic maximun path:
     * - Step 1)Get the max path from /path/to/widgets_new , EX: /path/to/widgets_new/path/to/longest/file
     * - Step 2)Excerpt /path/to/widgets_new from /path/to/widgets_new/path/to/longest/file EX: /path/to/longest/file
     * - Step 3)$intLengthPathToLongestFile = strlen(/path/to/longest/file);
     * - Step 4)$intLengthPathWPLogId = strlen(/path/to/repository/widgetPool/wpLogId);
     * - Step 5)$intLengthPathToLongestFile+$intLengthPathWPLogId < 255
     */
    protected function isCopyPathTooLong(){
        //Step 1)Get the max path from /path/to/widgets_new , EX: /path/to/widgets_new/path/to/longest/file
        $strPathWidgetsNew = $this->getPathWidgetsNewRelativePath();
        $intPathWPLogId = strlen($this->getPathWPLogId());
        $strLongestFilePathWidgetsNew = $this->objFramework->getIOFactory()->getFile()->getLongestFilePathInDir($strPathWidgetsNew);
        //Step 2)Excerpt /path/to/widgets_new from /path/to/widgets_new/path/to/longest/file EX: /path/to/longest/file
        $strLongestFilePathWidgetsNewExcerptPathWidgets = str_replace($strPathWidgetsNew, '', $strLongestFilePathWidgetsNew);
        //Step 3)$intLengthPathToLongestFile = strlen(/path/to/longest/file);
        $intLengthPathToLongestFile = strlen($strLongestFilePathWidgetsNewExcerptPathWidgets);
        //Step 4)$intLengthPathWPLogId = strlen(/path/to/repository/widgetPool/wpLogId);
        $intLengthPathWPLogId = strlen($this->getPathWPLogIdRelativePath());
        if(($intLengthPathToLongestFile + $intLengthPathWPLogId) > 255){
            $strLongestFilePathWidgetsNew = $this->objFramework->getIOFactory()->getFile()->getLongestFilePathInDir($strPathWidgetsNew);
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>It will occur copy fail because /path/to/source or /path/to/destination contains a long path exceed 255 length! [' . $this->getPathWPLogId() . $strLongestFilePathWidgetsNewExcerptPathWidgets . '(' . ($intLengthPathToLongestFile + $intLengthPathWPLogId) . ')]';
            throw new WFWidgetPoolWidgetPoolManagerException($message);
        }
    }
    /**
     *\brief Description 
     * -Update failed in step $this->updateWPUpdateLog($assocData);, 
     * -and cause /path/to/widgetPool/config.php => define('WP_HOME','/path/to/wpFailLogId')
     * -This method is can automatic reverse define('WP_HOME','/path/to/wpFailLogId') to define('WP_HOME','/path/to/wpLastSuccessLogId')
     */
    protected function changeCurrentPathToWPLastSuccessLogIdByBigestWpId(){
        $strPathDir = dirname(__FILE__) . '/../repository/widgetPool/*';
        $arrDir = glob($strPathDir, GLOB_ONLYDIR);
        $maxWpLogId = 0;
        if(is_array($arrDir) && $arrDir){
            foreach($arrDir as $strFullPathDir){
                $intWpLogId = substr(basename($strFullPathDir), 2);
                if($intWpLogId > $maxWpLogId){
                    $maxWpLogId = $intWpLogId;
                }
            }
        }
        $intLogIdLastSuccess = $maxWpLogId;
        $this->setLogId($intLogIdLastSuccess);
        $this->changeCurrentPathToWPLogId($intLogIdLastSuccess);
        return $intLogIdLastSuccess;
    }
    /**
     *\brief Description 
     * This method change /path/to/repository/widgets_new to /path/to/repository/widgets_new_old
     * @return boolean If success return true, return false is failed!
     */
    /*protected function mvWidgetsNewToWidgetsNewOld(){
        $strPathWidgetsNew = $this->getPathWidgetsNewRelativePath();
        $strPathWidgetsNewOld = $this->getPathWidgetsNewOldRelativePath();
        $isSuccess = $this->objFramework->getIOFactory()->getFile()->rename($strPathWidgetsNew, $strPathWidgetsNewOld);
        return $isSuccess;
    }*/
    /**
     *\brief Description 
     * This method change /path/to/repository/widgets_new_old to /path/to/repository/widgets_new
     * @return boolean If success return true, return false is failed!
     */
    /*protected function mvWidgetsNewOldToWidgetsNew(){
        $strPathWidgetsNew = $this->getPathWidgetsNewRelativePath();
        $strPathWidgetsNewOld = $this->getPathWidgetsNewOldRelativePath();
        $isSuccess = $this->objFramework->getIOFactory()->getFile()->rename($strPathWidgetsNewOld, $strPathWidgetsNew);
        return $isSuccess;
    }*/
    /**
     *\brief Description 
     * This method rm /path/to/repository/widgets_new_old if existed
     * @return boolean If success return true, return false is failed!
     */
    /*protected function rmWidgetsNewOld(){
        $strPathWidgetsNewOld = $this->getPathWidgetsNewOldRelativePath();
        if(true === file_exists($strPathWidgetsNewOld)){
            $this->objFramework->getIOFactory()->getFile()->rmdirRecurse($strPathWidgetsNewOld);
        }
    }*/
    /**
     *\brief Description 
     * This method is the main() proccess trigger update button
     * - Order of below process is relative! Please do not change any order!
     * @param $mixProductId $mixProductId wcu of $mixProductId need to update
     */
    public function updateWidget($mixProductId = null){
        //Settings environment variable
        //Because same machine is low-end
        ini_set('memory_limit', - 1); //no limit
        ini_set('max_execution_time', $this->objFramework->getConfigFactory()->getConfig()->getWpMaxExecutionTime()); //1800 seconds = 30 minutes
        
        $this->objFramework->getWidgetFactory()->getInterface()->analyzeWidgetsNewInfo();
        
        $strPathPidFile = $this->objWidgetPoolFactory->getWFHome() . '/repository/widgetpool.pid';
        $objMutex = $this->objWidgetPoolFactory->getIOFactory()->getMutex($strPathPidFile);
        $stepIndex = 0;
        $msg = '>>>>Step1: Start checking is Update widget process is mutex!';
        $this->objLogger->info($msg);
        if(true === $objMutex->isRunning()){
            $msg = 'Another Update widget process is running! There is not allowed concurrent Update widget proccess!';
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_IS_NOT_MUTEX);
        }
        $msg = '>>>>Step1: Finish checking is Update widget process is mutex!';
        $this->objLogger->info($msg);
        try{
            $msg = '>>>>Step2: Start getting NewLogId From WP_UPDATE_LOG';
            $this->objLogger->info($msg);
            $log_id = $this->getNewLogId();
            $msg = '>>>>Step2: Finish getting NewLogId : ' . $log_id;
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_GET_LOGID);
        }
        $this->setLogId($log_id);
        try{
            $msg = '>>>>Step3: Start checking is /path/to/src/widgets_new exist!';
            $this->objLogger->info($msg);
            $this->isFolderWidgetsNewExist();
            $msg = '>>>>Step3: Finish checking is /path/to/src/widgets_new exist!';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGETS_NEW_NOEXISTED);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGETS_NEW_NOEXISTED);
        }
        try{
            $msg = '>>>>Step4: Start checking is /path/to/src/widgets_new* is_readable!';
            $this->objLogger->info($msg);
            $this->isFolderWidgetsNewReadable();
            $msg = '>>>>Step4: Finish checking is /path/to/src/widgets_new* is_readable!';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGETS_NEW_NOREAD_PERMISSIONS);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGETS_NEW_NOREAD_PERMISSIONS);
        }
        try{
            $msg = '>>>>Step5: Start checking is /path/to/src/widgets_new* is_writable!';
            $this->objLogger->info($msg);
            $this->isFolderWidgetsNewWritable();
            $msg = '>>>>Step5: Finish checking is /path/to/src/widgets_new* is_writable!';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGETS_NEW_NOWRITE_PERMISSIONS);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGETS_NEW_NOWRITE_PERMISSIONS);
        }
        try{
            $msg = '>>>>Step6: Start checking is /path/to/src/repository/widgetPool is_readable!';
            $this->objLogger->info($msg);
            $this->isFolderWidgetPoolReadable();
            $msg = '>>>>Step6: Finish checking is /path/to/src/repository/widgetPool is_readable!';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGET_POOL_NOREAD_PERMISSIONS);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGET_POOL_NOREAD_PERMISSIONS);
        }
        try{
            $msg = '>>>>Step7: Start checking is /path/to/src/repository/widgetPool is_writable!';
            $this->objLogger->info($msg);
            $this->isFolderWidgetPoolWritable();
            $msg = '>>>>Step7: Finish checking is /path/to/src/repository/widgetPool is_writable!';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGET_POOL_NOWRITE_PERMISSIONS);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_WIDGET_POOL_NOWRITE_PERMISSIONS);
        }
        try{
            $msg = '>>>>Step8: Start checking is copy path is exceed 255 length constraints!';
            $this->objLogger->info($msg);
            $this->isCopyPathTooLong();
            $msg = '>>>>Step8: Finish checking is copy path is exceed 255 length constraints!';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_COPY_PATH_TOO_LONG);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_COPY_PATH_TOO_LONG);
        }
        $this->objWidgetPoolFactory->getDataObject()->beginTransaction();
        $msg = '-----------Start Transaction---------------------------';
        $this->objLogger->info($msg);
        try{
            $msg = '>>>>Step9: Start update WP_UPDATE_LOG.before_update_widgets & WP_UPDATE_LOG.before_update_widget_components in json format before execute interface synWidgetXMLToDB.php & synWidgetComponentXMLToDB.php';
            $this->objLogger->info($msg);
            $this->updateAssocsBeforeUpdateWidgetAndWidgetComponentsToTableWpUpdateLog();
            $msg = '>>>>Step9: Finish update WP_UPDATE_LOG.before_update_widgets & WP_UPDATE_LOG.before_update_widget_components in json format before execute interface synWidgetXMLToDB.php & synWidgetComponentXMLToDB.php';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step9: update WP_UPDATE_LOG.before_update_widgets & WP_UPDATE_LOG.before_update_widget_components in json format before execute interface synWidgetXMLToDB.php & synWidgetComponentXMLToDB.php';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_UPDATE_BEFORE_UPDATE_WIDGETS);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_REMOVE_WIDGETS_NEW_OLD);
        }
        /*try{
            $msg = '>>>>Step10: Start removing /path/to/repository/widgetPool/widgets_new_old';
            $this->objLogger->info($msg);
            $this->rmWidgetsNewOld();
            $msg = '>>>>Step10: Finish removing /path/to/repository/widgetPool/widgets_new_old';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step10: removing /path/to/repository/widgetPool/widgets_new_old';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_REMOVE_WIDGETS_NEW_OLD);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_REMOVE_WIDGETS_NEW_OLD);
        }*/
        try{
            $msg = '>>>>Step11: Start mkdirWPLogId : creating folder ' . $this->getPathWPLogId();
            $this->objLogger->info($msg);
            $this->mkdirWPLogId();
            $msg = '>>>>Step11: Finish mkdirWPLogId : creating folder ' . $this->getPathWPLogId();
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step11: mkdirWPLogId : creating folder ' . $this->getPathWPLogId();
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_MKDIR_WPLOGID);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_MKDIR_WPLOGID);
        }
        try{
            $msg = '>>>>Step12: Start copying folder /path/to/widgets_new/* to /path/to/wpLogId excerpt /path/to/widgets_new/widget & /path/to/widgets_new/widgetComponent';
            $this->objLogger->info($msg);
            $this->copyWidgetsNewToWPLogIdExcerptWidgetAndWidgetComponent();
            $msg = '>>>>Step12: Finish copying folder /path/to/widgets_new/* to /path/to/wpLogId excerpt /path/to/widgets_new/widget';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step12: copying folder /path/to/widgets_new/* to /path/to/wpLogId excerpt /path/to/widgets_new/widget & /path/to/widgets_new/widgetComponent';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_COPY_WIDGETS_NEW_TO_WPLOGID);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_COPY_WIDGETS_NEW_TO_WPLOGID);
        }
        try{
            $msg = '>>>>Step13: Start copying /path/to/widgetPool/wpCurrent/widget & /path/to/widgetPool/wpCurrent/widgetComponent to /path/to/widgetPool/wpLogId/.';
            $this->objLogger->info($msg);
            $this->copyCurrentWidgetAndWidgetComponentToWPLogId();
            $msg = '>>>>Step13: Finish copying /path/to/widgetPool/wpCurrent/widget & /path/to/widgetPool/wpCurrent/widgetComponent to /path/to/widgetPool/wpLogId/.';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step13: copying /path/to/widgetPool/wpCurrent/widget & /path/to/widgetPool/wpCurrent/widgetComponent to /path/to/widgetPool/wpLogId/.';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_COPY_CURRENT_WIDGET_AND_WIDGET_COMPONENT_TO_WPLOGID);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_COPY_CURRENT_WIDGET_TO_WPLOGID);
        }
        try{
            $msg = '>>>>Step14: Start adding or upgrading /path/to/widget_news/widget/modNewWidget & /path/to/widget_news/widgetComponent/comNewWidgetComponent to /path/to/widgetPool/wpLogId/widget/. & /path/to/widgetPool/wpLogId/widgetComponent/.';
            $this->objLogger->info($msg);
            $this->addOrUpgradeWidgetFromWidgetsNew();
            $this->addOrUpgradeWidgetComponentFromWidgetsNew($mixProductId);
            $msg = '>>>>Step14: Finish adding or upgrading /path/to/widget_news/widget/modNewWidget & /path/to/widget_news/widgetComponent/comNewWidgetComponent to /path/to/widgetPool/wpLogId/widget/. & /path/to/widgetPool/wpLogId/widgetComponent/.';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step14: adding or upgrading /path/to/widget_news/widget/modNewWidget & /path/to/widget_news/widgetComponent/comNewWidgetComponent to /path/to/widgetPool/wpLogId/widget/. & /path/to/widgetPool/wpLogId/widgetComponent/.';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_ADDORUPGRADE_WIDGET_AND_WIDGET_COMPONENT_TO_WPLOGID);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_ADDORUPGRADE_WIDGET_AND_WIDGET_COMPONENT_TO_WPLOGID);
        }
        try{
            $msg = '>>>>Step15: Start changing define("WP_WEBROOT","/widgetPool/wpCurrent"); to  define("WP_WEBROOT","/widgetPool/wpLogId");';
            $this->objLogger->info($msg);
            $this->changeCurrentPathToWPLogId();
            $msg = '>>>>Step15: Finish changing define("WP_WEBROOT","/widgetPool/wpCurrent"); to  define("WP_WEBROOT","/widgetPool/wpLogId");';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step15: changing define("WP_WEBROOT","/widgetPool/wpCurrent"); to  define("WP_WEBROOT","/widgetPool/wpLogId");';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_CHANGE_WP_PATH_TO_WPLOGID);
            $this->rmFolderWPLogId();
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_CHANGE_WP_PATH_TO_WPLOGID);
        }
        try{
            $msg = '>>>>Step16: Start excuting all the filter policy which existed in Table WF_UPDATE_FILTER';
            $this->objLogger->info($msg);
            $this->objWidgetPoolFactory->getWidgetPoolDB()->execDBUpdateFilter();
            $msg = '>>>>Step16: Finish excuting all the filter policy which existed in Table WF_UPDATE_FILTER';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step16: excuting all the filter policy which existed in Table WF_UPDATE_FILTER';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_EXEC_DB_UPDATE_FILTER);
            $this->rmFolderWPLogId();
            $intLogIdLastSuccess = $this->getLogIdLastSuccess();
            $this->changeCurrentPathToWPLogId($intLogIdLastSuccess);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_EXEC_DB_UPDATE_FILTER);
        }
        /*try{
            $msg = '>>>>Step17: Start changing /path/to/widgets_new to  /path/to/widgets_new_old';
            $this->objLogger->info($msg);
            $this->mvWidgetsNewToWidgetsNewOld();
            $msg = '>>>>Step17: Finish changing /path/to/widgets_new to  /path/to/widgets_new_old';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            //if /path/to/widgets_new rm failed do not need to rollback
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step17: changing /path/to/widgets_new to  /path/to/widgets_new_old';
            $this->objLogger->info($msg);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_RM_WIDGETS_NEW);
            $this->rmFolderWPLogId();
            $intLogIdLastSuccessByBigestWpId = $this->changeCurrentPathToWPLastSuccessLogIdByBigestWpId();
            $this->objLogger->error("UpdateRollBack  : changeCurrentPathToWPLastSuccessLogIdByBigestWpId=>" . $intLogIdLastSuccessByBigestWpId);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_RM_WIDGETS_NEW);
        }*/
        try{
            $msg = '>>>>Step17: Start update result to /path/to/repository/widgets_new_info.xml';
            $this->objLogger->info($msg);
            $this->updateSuccessResultToWidgetsNewInfoXml($mixProductId);
            $msg = '>>>>Step17: Finish update result to /path/to/repository/widgets_new_info.xml';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            //if /path/to/widgets_new rm failed do not need to rollback
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step17: update result to /path/to/repository/widgets_new_info.xml';
            $this->objLogger->info($msg);
            $this->updateFailedResultToWidgetsNewInfoXml($mixProductId);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_RM_WIDGETS_NEW);
            $this->rmFolderWPLogId();
            $intLogIdLastSuccessByBigestWpId = $this->changeCurrentPathToWPLastSuccessLogIdByBigestWpId();
            $this->objLogger->error("UpdateRollBack  : changeCurrentPathToWPLastSuccessLogIdByBigestWpId=>" . $intLogIdLastSuccessByBigestWpId);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_RM_WIDGETS_NEW);
        }
        try{
            $msg = '>>>>Step18: Start updating WIDGETPOOL_UPDATELOG_STATUS_SUCCESS WHERE WP_UPDATE_LOG.log_id=$this->log_id';
            $this->objLogger->info($msg);
            $assocData = array();
            $assocData['status'] = WFWidgetPoolOpt::WIDGETPOOL_UPDATELOG_STATUS_SUCCESS;
            $this->updateWPUpdateLog($assocData);
            $msg = '>>>>Step18: Finish updating WIDGETPOOL_UPDATELOG_STATUS_SUCCESS WHERE WP_UPDATE_LOG.log_id=$this->log_id';
            $this->objLogger->info($msg);
        }catch(Exception $e){
            // if Updating WIDGETPOOL_UPDATELOG_STATUS_SUCCESS failed do not need to rollback
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step18: Updating WIDGETPOOL_UPDATELOG_STATUS_SUCCESS WHERE WP_UPDATE_LOG.log_id=$this->log_id';
            $this->objLogger->info($msg);
            //$this->mvWidgetsNewOldToWidgetsNew();
            $this->updateFailedResultToWidgetsNewInfoXml($mixProductId);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_UPDATE_SUCCESS_STATUS);
            $this->rmFolderWPLogId();
            $intLogIdLastSuccessByBigestWpId = $this->changeCurrentPathToWPLastSuccessLogIdByBigestWpId();
            $this->objLogger->error("UpdateRollBack  : changeCurrentPathToWPLastSuccessLogIdByBigestWpId=>" . $intLogIdLastSuccessByBigestWpId);
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_UPDATE_SUCCESS_STATUS);
        }
        $msg = '>>>>Step19: Start synServerListType.php update!';
        $this->objLogger->info($msg);
        try{
            $strPathServerlistXML = $this->getPathWPLogId() . '/config/serverlist.xml';
            $this->objFramework->getWidgetFactory()->getInterface()->synServerListTypeUpdate($strPathServerlistXML);
        }catch(Exception $e){
            $this->objWidgetPoolFactory->getDataObject()->rollBack();
            $msg = '-----------Rollback Transaction in Step19: Start synServerListType.php update!';
            $this->objLogger->info($msg);
            //$this->mvWidgetsNewOldToWidgetsNew();
            $this->updateFailedResultToWidgetsNewInfoXml($mixProductId);
            $this->updateFailedStatusToTableWpUpdateLog(WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_EXEC_INTERFACE_SYN_SERVERLISTTYPE);
            $this->rmFolderWPLogId();
            $intLogIdLastSuccessByBigestWpId = $this->changeCurrentPathToWPLastSuccessLogIdByBigestWpId();
            $this->objLogger->error("UpdateRollBack  : changeCurrentPathToWPLastSuccessLogIdByBigestWpId=>" . $intLogIdLastSuccessByBigestWpId);
            $msg = __CLASS__ . '::' . __FUNCTION__ . '()=>Failed to execute php synServerListType.php update!';
            throw new WFWidgetPoolWidgetPoolManagerException($msg, WFWidgetPoolOpt::WIDGETPOOL_UPDATE_FAILED_EXEC_INTERFACE_SYN_SERVERLISTTYPE);
        }
        $msg = '>>>>Step19: Finish synServerListType.php update!';
        $this->objLogger->info($msg);
        $this->objWidgetPoolFactory->getDataObject()->commit();
        $msg = '-----------Commit Transaction---------------------------';
        $this->objLogger->info($msg);
        try{
            $intLogIdLastLastSuccess = $this->getLogIdLastLastSuccess();
            if($intLogIdLastLastSuccess){ //If got $intLogIdLastLastSuccess
                $this->rmFolderWPLogId($intLogIdLastLastSuccess);
                $msg = '>>>>Step20: Start removing folder /path/to/widgetPool/wpLogIdLastLastSuccess';
                $this->objLogger->info($msg);
                $this->objLogger->debug('GET intLogIdLastLastSuccess:' . $intLogIdLastLastSuccess);
                $msg = '>>>>Step20: Finish removing folder /path/to/widgetPool/wpLogIdLastLastSuccess';
                $this->objLogger->info($msg);
            }
        }catch(Exception $e){
            $msg = $this->objLogger->getMessageByException($e);
            $this->objLogger->error($msg);
            throw new WFWidgetPoolWidgetPoolManagerException($msg);
        }
    }
    /**
     *\brief Description:
     * - Update failed status to Table WP_UPDATE_LOG
     */
    protected function updateFailedStatusToTableWpUpdateLog($intFailPoint){
        $assocData = array();
        $assocData['status'] = WFWidgetPoolOpt::WIDGETPOOL_UPDATELOG_STATUS_FAILED;
        $assocData['fail_point'] = $intFailPoint;
        $this->updateWPUpdateLog($assocData);
    }
    /**
     *\brief Description:
     * - Get Is got new widget in db which determine by edittime(lastupdate) within 14 days
     * @return  boolean return numberNewWidget is got new widget, return false is without new widget
     */
    public function isNewWidget(){
        $shownew_days = $this->objConfig->getShownewDays();
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->setPrimaryKey('widget_id');
        $objParameter->appendFrom('WIDGET');
        $objParameter->andWhereEqual('widget_status', '1');
        $intTimestampForShowdays = strtotime("-" . $shownew_days . " day");
        $objParameter->andWhereGte('edittime', $intTimestampForShowdays);
        $numberWidget = $this->objWidgetPoolFactory->getDataObject()->querySelectCountByParameter($objParameter);
        return $numberWidget ? $numberWidget : false;
    }
    /**
     *\brief Description:
     * - Get LastSuccess WP_UPDATE_LOG.log_id 
     * - Use to Error handle, If update failed, current WP_PATH will roll back to /path/to/widgetPool/wpLastSuccessId
     * @return mix LastSuccess WP_UPDATE_LOG.log_id if success, false if failed
     */
    protected function getLogIdLastSuccess($intLogIdCurrent = null){
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->appendFrom("WP_UPDATE_LOG");
        $objParameter->appendSelect("log_id");
        $objParameter->andWhereEqual("status", '1');
        if(null !== $intLogIdCurrent){
            $objParameter->andWhereLte('log_id', $intLogIdCurrent);
        }
        $objParameter->setOrderBy("log_id DESC");
        $objParameter->setLimit(0, 1);
        $intLogIdLastSuccess = $this->objWidgetPoolFactory->getDataObject()->querySelectOneByParameter($objParameter);
        if(false === $intLogIdLastSuccess){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>SELECT log_id FROM WP_UPDATE_LOG WHERE status=1 ORDER BY log_id DESC LIMIT 0,1 failed! Err Msg:' . $this->objWidgetPoolFactory->getDataObject()->getErrMessage();
            throw new WFDbDatabaseObjectException($message);
        }
        return $intLogIdLastSuccess ? $intLogIdLastSuccess : false;
    }
    /**
     *\brief Description:
     * - Get LastLastSuccess WP_UPDATE_LOG.log_id
     * - Use for remove folder /path/to/widgetPool/wpLastLastSuccessId
     * @return mix LastLastSuccess WP_UPDATE_LOG.log_id if success, false if failed
     */
    protected function getLogIdLastLastSuccess($intLogIdCurrent = null){
        $intLogIdCurrent = null !== $intLogIdCurrent ? $intLogIdCurrent : $this->log_id;
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->appendFrom("WP_UPDATE_LOG");
        $objParameter->appendSelect("log_id");
        $objParameter->andWhereEqual("status", '1');
        $objParameter->andWhereLt('log_id', $intLogIdCurrent);
        $objParameter->setOrderBy("log_id DESC");
        $objParameter->setLimit(0, 2);
        $arrsData = $this->objWidgetPoolFactory->getDataObject()->querySelectAllByParameter($objParameter);
        if(false === $arrsData){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>SELECT log_id FROM WP_UPDATE_LOG WHERE status=1 AND log_id<? ORDER BY log_id DESC LIMIT 0,2 failed! Err Msg:' . $this->objWidgetPoolFactory->getDataObject()->getErrMessage();
            throw new WFDbDatabaseObjectException($message);
        }
        if(! (is_array($arrsData) && $arrsData)){
            return null;
        }
        $intLogIdLastLastSuccess = false;
        $numberArrsData = count($arrsData);
        if('2' == $numberArrsData){
            $arrData = $arrsData['1'];
            $intLogIdLastLastSuccess = $arrData['log_id'];
        }
        return $intLogIdLastLastSuccess ? $intLogIdLastLastSuccess : false;
    }
    /**
     *\brief Description:
     * - Remove folder /path/to/widgetPool/wpLogId 
     * - If Remove failed, will raised Exception
     * @param $intLogId if $intLogId=null, $intLogId=$this->current_update_log_id
     */
    protected function rmFolderWPLogId($intLogId = null){
        $intLogId = $this->getWPLogId($intLogId);
        if(false === $this->isOriginalLogId($intLogId)){ //avoid delete original /path/to/widgetPool/wp1
            $strPath = $this->getPathWPLogIdRelativePath($intLogId);
            try{
                $this->objWidgetPoolFactory->getIOFactory()->getFile()->rmdirRecurse($strPath);
            }catch(Exception $e){
                $message = $e;
                throw new WFWidgetPoolWidgetPoolManagerException($message);
            }
        }
    }
    /**
     *\brief Description
     * - This method check isOriginal log_id
     */
    protected function isOriginalLogId($intLogId){
        $ret = ($intLogId == '1') ? true : false;
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get the new log_id from TableWPUpdateLog after Insert
     * @param $intLogIdToNew You can specify $intLogIdToNew to Insert
     * @return mix If success return lastInsert log_id, If failed return false
     */
    protected function getNewLogId($intLogIdToNew = null){
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->appendFrom('WP_UPDATE_LOG');
        $assocData = array();
        //$assocData['log_id'] = null;
        if(null !== $intLogIdToNew){
            $assocData['log_id'] = $intLogIdToNew;
        }
        $assocData['createtime'] = time();
        $objParameter->setAssocData($assocData);
        $result = $this->objWidgetPoolFactory->getDataObject()->queryInsertByParameter($objParameter);
        if(false === $result){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>INSERT WP_UPDATE_LOG failed! Err Msg:' . $this->objWidgetPoolFactory->getDataObject()->getErrMessage();
            throw new WFDbDatabaseObjectException($message);
        }
        //echo $sql;
        $this->log_id = $this->objWidgetPoolFactory->getDataObject()->lastInsertId();
        return $this->log_id;
    }
    /**
     *\brief Description
     * - create folder /path/to/widgetPool/wpLogId
     * @return boolean If success return true, if failed return false. Default is true
     */
    protected function mkdirWPLogId(){
        $ret = true;
        $strPathDir = $this->getPathWPLogIdRelativePath();
        if(false === file_exists($strPathDir)){
            $ret = $this->objWidgetPoolFactory->getIOFactory()->getFile()->mkdir($strPathDir);
            if(false === $ret){
                $message = __CLASS__ . '::' . __FUNCTION__ . '()=>mkdir /path/to/widgetPool/wpLogId Error!';
                throw new WFWidgetPoolWidgetPoolManagerException($message);
            }
        }
        return $ret;
    }
    /**
     *\brief Description
     * - Copy /path/to/widgets_new/* to /path/to/wpLogId excerpt /path/to/widgets_new/widget &  /path/to/widgets_new/widgetComponent
     * @return boolean If success return true, if failed return false.
     */
    protected function copyWidgetsNewToWPLogIdExcerptWidgetAndWidgetComponent(){
        $strPathWidgetsNew = $this->getPathWidgetsNewRelativePath();
        //$strPathWidget = $this->strWPRoot.'/wp'.$this->log_id;
        $strPathDest = $this->getPathWPLogIdRelativePath();
        $isSuccessCopyRecurse = $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathWidgetsNew, $strPathDest);
        $strPathExcerptWidget = $strPathDest . '/widget';
        $isSuccessRmdirRecurseWidget = $this->objWidgetPoolFactory->getIOFactory()->getFile()->rmdirRecurse($strPathExcerptWidget);
        $strPathExcerptWidgetComponent = $strPathDest . '/widgetComponent';
        $isSuccessRmdirRecurseWidgetComponent = $this->objWidgetPoolFactory->getIOFactory()->getFile()->rmdirRecurse($strPathExcerptWidgetComponent);
        return $isSuccessCopyRecurse && $isSuccessRmdirRecurseWidget && $isSuccessRmdirRecurseWidgetComponent;
    }
    /**
     *\brief Description
     * - Copy /path/to/widgetPool/wpCurrent/widget to /path/to/widgetPool/wpLogId/.
     * @return boolean If success return true, if failed return false.
     */
    protected function copyCurrentWidgetAndWidgetComponentToWPLogId(){
        $strPathCurrentWidget = $this->getWPHomeRelativePath() . '/widget';
        $strPathDest = $this->getPathWPLogIdRelativePath() . '/widget';
        $isSuccessCopyRecurseWidget = $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathCurrentWidget, $strPathDest);
        $strPathCurrentWidgetComponent = $this->getWPHomeRelativePath() . '/widgetComponent';
        $strPathDest = $this->getPathWPLogIdRelativePath() . '/widgetComponent';
        $isSuccessCopyRecurseWidgetComponent = $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathCurrentWidgetComponent, $strPathDest);
        return $isSuccessCopyRecurseWidget && $isSuccessCopyRecurseWidgetComponent;
    }
    /**
     *\brief Description
     * - Add /path/to/widget_news/widget/modNewWidget to /path/to/widgetPool/wpLogId/widget/.
     * - EX : Upgrade /path/to/widget_news/widget/modTodo which version is 2.0 to /path/to/widgetPool/wpLogId/widget/modTodo is 1.0
     */
    abstract protected function addOrUpgradeWidgetFromWidgetsNew();
    /*protected function addOrUpgradeWidgetFromWidgetsNew(){
        $arrDir = glob($this->getPathWidgetsNew() . '/widget/*', GLOB_ONLYDIR);
        if(is_array($arrDir) && $arrDir){
            foreach($arrDir as $strFullPathDir){
                $strWidgetName = basename($strFullPathDir);
                $strPathWidgetWPLogId = $this->getPathWPLogId() . '/widget/' . $strWidgetName;
                if(false === file_exists($strPathWidgetWPLogId)){
                    $this->addWidgetFromWidgetsNewByWidgetName($strWidgetName);
                }else{
                    $this->upgradeWidgetFromWidgetsNewByWidgetName($strWidgetName);
                }
            }
        }
    }*/
    /**
     *\brief Description
     * - Add /path/to/widget_news/widget/modNewWidget to /path/to/widgetPool/wpLogId/widget/.
     */
    protected function addWidgetFromWidgetsNewByWidgetName($strWidgetName){
        // Step1: Copy /path/to/widgets_news/modHaveToAdd to /path/to/widgetPool/wpLogId/widget/.
        $strPathCurrentWidget = $this->getPathWidgetsNew() . '/widget/' . $strWidgetName;
        $strPathDest = $this->getPathWPLogId() . '/widget/' . $strWidgetName;
        $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathCurrentWidget, $strPathDest);
        // Step2: synWidgetXml of modHaveToAdd
        $strPathWidget = $this->getPathWPLogId() . '/widget/' . $strWidgetName;
        $this->objWidgetPoolFactory->getWidgetPoolDB()->synWidgetDataToDBByWidgetPath($strPathWidget);
    }
    protected static $instance;
    /**
     *\brief Description
     * - Get assocs widget array from /path/to/widgets_new/widget
     */
    public function getAssocsWidgetTypeWithWidgetAllFromWidgetsNew(){
        $strPathWidgetPackage = $this->getPathWidgetsNew() . '/widget';
        $ret = $this->getAssocsWidgetTypeWithWidgetAllByWidgetPackagePath($strPathWidgetPackage);
        return $ret;
    }
    /**
     *\brief Description
     * - Get assocs widget array from /path/to/repository/widgetPool/wpCurrent/widget
     */
    public function getAssocsWidgetTypeWithWidgetAllFromWpCurrent(){
        $strPathWidgetPackage = $this->getWPHome() . '/widget';
        $ret = $this->getAssocsWidgetTypeWithWidgetAllByWidgetPackagePath($strPathWidgetPackage);
        return $ret;
    }
    /**
     *\brief Description
     * - Get assocs widget array by input /path/to/widget_news/widget
     * - Example:
     * array (
              1 => 
              array (
                'modPolicyList' => 
                array (
                  'widget_name' => 'modPolicyList',
                  'modname' => 'modPolicyList',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '3.0',
                ),
                'modSample' => 
                array (
                  'widget_name' => 'modSample',
                  'modname' => 'modSample',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
                'modSample2' => 
                array (
                  'widget_name' => 'modSample2',
                  'modname' => 'modSample2',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
                'modSample3' => 
                array (
                  'widget_name' => 'modSample3',
                  'modname' => 'modSample3',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
                'modZMultiple' => 
                array (
                  'widget_name' => 'modZMultiple',
                  'modname' => 'modZMultiple',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
              ),
            );
     */
    protected function getAssocsWidgetTypeWithWidgetAllByWidgetPackagePath($strPathWidgetPackage){
        $key = base64_encode($strPathWidgetPackage);
        if(!isset(self::$instance[__FUNCTION__][$key])){
            $arrDir = glob($strPathWidgetPackage.'/*', GLOB_ONLYDIR);
            $ret = array();
            if(is_array($arrDir) && $arrDir){
                foreach($arrDir as $strFullPathDir){
                    $strPathWidgetXml = $strFullPathDir.'/widget.xml';
                    $assocDataWidgetXmlFull = $this->objFramework->getDomFactory()->getSimplexml($strPathWidgetXml)->toArray();
                    $assocDataWidgetXmlPart = array();
                    $assocDataWidgetXmlPart['widget_name'] = $assocDataWidgetXmlFull['widget_name'];
                    $assocDataWidgetXmlPart['modname'] = $assocDataWidgetXmlFull['modname'];
                    $assocDataWidgetXmlPart['widget_version'] = $assocDataWidgetXmlFull['widget_version'];
                    $assocDataWidgetXmlPart['widget_type'] = $assocDataWidgetXmlFull['widget_type'];
                    $assocDataWidgetXmlPart['widget_min_wf_version'] = $assocDataWidgetXmlFull['widget_min_wf_version'];
                    
                    $ret[$assocDataWidgetXmlPart['widget_type']][$assocDataWidgetXmlPart['widget_name']] = $assocDataWidgetXmlPart;
                }
            }
            self::$instance[__FUNCTION__][$key] = $ret;
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     *\brief Description
     * - Get assocs widgetComponent array from /path/to/widgets_new/widgetComponent by $intProductId
     */
    protected function getAssocsWcomponentNameWithWidgetComponentFromWidgetsNewByProductId($intProductId){
        $ret = array();
        $assocsProductIdWithWidgetComponentFromWidgetsNew = $this->getAssocsProductIdWithWidgetComponentFromWidgetsNew();
        //var_dump($assocsProductIdWithWidgetComponentFromWidgetsNew);
        if(is_array($assocsProductIdWithWidgetComponentFromWidgetsNew) && $assocsProductIdWithWidgetComponentFromWidgetsNew){
            foreach($assocsProductIdWithWidgetComponentFromWidgetsNew as $strProductIdAndCatetoryName => $assocsWidgetComponent){
                list($product_id, $category_name) = explode('::',$strProductIdAndCatetoryName);
                if($product_id == $intProductId){
                    $ret = $assocsWidgetComponent;
                    break;
                }
            }
        }
        return $ret;
    }
    /**
     *\brief Description
     * - Get assocs widgetComponent array from /path/to/widgets_new/widgetComponent
     */
    public function getAssocsProductIdWithWidgetComponentFromWidgetsNew(){
        $strPathWidgetComponentPackage = $this->getPathWidgetsNew() . '/widgetComponent';
        $ret = $this->getAssocsProductIdWithWidgetComponentByWidgetComponentPackagePath($strPathWidgetComponentPackage);
        return $ret;
    }
    /**
     *\brief Description
     * - Get assocs widgetComponent array from /path/to/repository/widgetPool/wpCurrent/widgetComponent
     */
    public function getAssocsProductIdWithWidgetComponentFromWpCurrent(){
        $strPathWidgetComponentPackage = $this->getWPHome() . '/widgetComponent';
        $ret = $this->getAssocsProductIdWithWidgetComponentByWidgetComponentPackagePath($strPathWidgetComponentPackage);
        return $ret;
    }
    /**
     *\brief Description
     * - Get assocs widget array by input /path/to/widget_news/widget
     * - Example:
     * array (
              1 => 
              array (
                'modPolicyList' => 
                array (
                  'widget_name' => 'modPolicyList',
                  'modname' => 'modPolicyList',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '3.0',
                ),
                'modSample' => 
                array (
                  'widget_name' => 'modSample',
                  'modname' => 'modSample',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
                'modSample2' => 
                array (
                  'widget_name' => 'modSample2',
                  'modname' => 'modSample2',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
                'modSample3' => 
                array (
                  'widget_name' => 'modSample3',
                  'modname' => 'modSample3',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
                'modZMultiple' => 
                array (
                  'widget_name' => 'modZMultiple',
                  'modname' => 'modZMultiple',
                  'widget_version' => '1.0',
                  'widget_type' => '1',
                  'widget_min_wf_version' => '2.0',
                ),
              ),
            );
     */
    protected function getAssocsProductIdWithWidgetComponentByWidgetComponentPackagePath($strPathWidgetComponentPackage){
        $key = base64_encode($strPathWidgetComponentPackage);
        if(!isset(self::$instance[__FUNCTION__][$key])){
            $arrDir = glob($strPathWidgetComponentPackage.'/*', GLOB_ONLYDIR);
            $ret = array();
            if(is_array($arrDir) && $arrDir){
                foreach($arrDir as $strFullPathDir){
                    $strPathWidgetComponentXml = $strFullPathDir.'/component.xml';
                    $assocDataWidgetComponentXmlFull = $this->objFramework->getDomFactory()->getSimplexml($strPathWidgetComponentXml)->toArray();
                    //var_dump($assocDataWidgetComponentXmlFull);exit();
                    $assocDataWidgetComponentXmlPart = array();
                    $assocDataWidgetComponentXmlPart['wcomponent_name'] = $assocDataWidgetComponentXmlFull['wcomponent_name'];
                    $assocDataWidgetComponentXmlPart['wcomponent_version'] = $assocDataWidgetComponentXmlFull['wcomponent_version'];
                    $assocDataWidgetComponentXmlPart['wcomponent_min_support_version'] = $assocDataWidgetComponentXmlFull['wcomponent_min_support_version'];
                    ///var_dump($assocDataWidgetComponentXmlFull['categories']);exit();
                    $assocsCategory = $this->getArrsDataWidgetComponentCategoryByArrDataXML($assocDataWidgetComponentXmlFull);
                    //var_dump($assocsCategory);exit();
                    if(is_array($assocsCategory) && $assocsCategory){
                        foreach($assocsCategory as $assocCategory){
                            // I want to use one index save two value, so I use symbol :: to concate two string
                            $strProductIdAndCatetoryName = $assocCategory['category_product_id'].'::'.$assocCategory['category_name'];
                            $ret[$strProductIdAndCatetoryName][$assocDataWidgetComponentXmlPart['wcomponent_name']] = $assocDataWidgetComponentXmlPart;
                        }
                    }
                }
            }
            self::$instance[__FUNCTION__][$key] = $ret;
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     *\brief Description
     * - EX : Upgrade /path/to/widget_news/widget/modTodo which version is 2.0 to /path/to/widgetPool/wpLogId/widget/modTodo is 1.0
     * - If widget version is compatible with Widget Framework,
     * Below is upgrade three scenerio:
     * 1)version /path/to/widgets_new/widget/modA    equal     /path/to/widgetPool/widget/modA => upgrade
     * 2)version /path/to/widgets_new/widget/modA greater than /path/to/widgetPool/widget/modA => upgrade
     * 3)version /path/to/widgets_new/widget/modA   less than  /path/to/widgetPool/widget/modA => do nothing
     */
    protected function upgradeWidgetFromWidgetsNewByWidgetName($strWidgetName){
        $strPathWidgetXMLInWidgetsNew = $this->getPathWidgetsNewRelativePath() . '/widget/' . $strWidgetName . '/widget.xml';
        if(! file_exists($strPathWidgetXMLInWidgetsNew)){
            $strMsg = __CLASS__ . '::' . __FUNCTION__ . '()=>widget.xml does not existed!';
            throw new WFWidgetPoolWidgetPoolManagerException($strMsg);
        }
        $arrDataWidgetInWidgetsNew = $this->objWidgetPoolFactory->getWidgetPoolManager()->getArrDataWidgetByWidgetPath($strPathWidgetXMLInWidgetsNew);
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->appendFrom('WIDGET');
        $objParameter->andWhereEqual('widget_name', $strWidgetName);
        $arrDataWidgetInLocal = $this->objWidgetPoolFactory->getDataObject()->querySelectRowByParameter($objParameter);
        $floatVersionWidgetInWidgetsNew = $this->objFramework->getTypeFactory()->getString()->getVersionFloatByString($arrDataWidgetInWidgetsNew['widget_version']);
        $floatVersionWidgetInLocal = isset($arrDataWidgetInLocal['widget_version_float']) ? $arrDataWidgetInLocal['widget_version_float'] : 0;
        $isWidgetInWidgetsNewCompatibleWithWf = $this->objWidgetPoolFactory->getWidgetPoolDB()->isWidgetCompatibleWithWf($arrDataWidgetInWidgetsNew);
        if(true === $isWidgetInWidgetsNewCompatibleWithWf && $floatVersionWidgetInWidgetsNew >= $floatVersionWidgetInLocal){
            // Step1: Delete /path/to/wpLogId/modHaveToUpgrade
            ////$strPath = $this->getPathWPLogId() . '/widget/' . $strWidgetName;
            ////$this->objWidgetPoolFactory->getIOFactory()->getFile()->rmdirRecurse($strPath);
            // Step2: Copy /path/to/widgets_news/modHaveToAdd to /path/to/widgetPool/wpLogId/widget/.
            $strPathCurrentWidget = $this->getPathWidgetsNew() . '/widget/' . $strWidgetName;
            $strPathDest = $this->getPathWPLogId() . '/widget/' . $strWidgetName;
            $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathCurrentWidget, $strPathDest);
            // Step3: synWidgetXml of modHaveToUpgrade
            $strPathWidget = $this->getPathWPLogId() . '/widget/' . $strWidgetName;
            $this->objWidgetPoolFactory->getWidgetPoolDB()->synWidgetDataToDBByWidgetPath($strPathWidget);
        }
    }
    /**
     *\brief Description
     * - Get Content of /path/to/widgetPool/config.php
     * - EX : 
     * <?php
     * if(!defined('WP_WEBROOT')){
     * define("WP_WEBROOT",'/repository/widgetPool/wp1');
     * define("WP_HOME",dirname(__FILE__).'/..'.WP_WEBROOT);
     * }
     */
    protected function getContentWPConfig(){
        $strPathWidgetPoolConfig = $this->getPathWPConfig();
        $contentConfig = file_get_contents($strPathWidgetPoolConfig);
        if(false === $contentConfig){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>Error!Can\'t read content from /path/to/widgetPool/config.php!';
            throw new WFWidgetPoolWidgetPoolManagerException($message);
        }
        return $contentConfig;
    }
    /**
     *\brief Description:
     * - Change variable define("WP_WEBROOT",'/widgetPool/wpCurrent');
     * - to define("WP_WEBROOT",'/widgetPool/wpLogId');
     * - Which define in /path/to/widgetPool/config.php
     * @param $intLogId You can specify $intLogId to change the content to define("WP_WEBROOT",'/widgetPool/wp$intLogId');
     */
    public function changeCurrentPathToWPLogId($intLogId = null){
        $strPathWidgetPoolConfig = $this->getPathWPConfig();
        $intLogIdHaveToReplace = $intLogId == null ? $this->log_id : $intLogId;
        $contentConfig = '<?php
//If modify this file, please synchronize with /path/to/src/inc/class/widgetPool/widget/WidgetPoolManager.abstract.php
if(!defined(\'WP_WEBROOT\')){
    define("WP_WEBROOT_NO_SLASH",\'repository/widgetPool/wp' . $intLogIdHaveToReplace . '\');
    define("WP_WEBROOT",\'/\'.WP_WEBROOT_NO_SLASH);
    define("WP_HOME",dirname(__FILE__).\'/../..\'.WP_WEBROOT);
}';
        $isSuccess = $this->objFramework->getIOFactory()->getFile()->writeDataSafe($strPathWidgetPoolConfig, 'w+', $contentConfig);
        if(false === $isSuccess){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>Error!Fail to fwrite /path/to/widgetPool/config.php!';
            throw new WFWidgetPoolWidgetPoolManagerException($message);
        }
        return $isSuccess;
    }
    /**
     *\brief Description
     * - Update $assocData WHERE WP_UPDATE_LOG.log_id=$this->log_id
     * @param array $assocData Data have to update
     * @return boolean If success return true, if failed return false
     */
    protected function updateWPUpdateLog($assocData){
        $log_id = $this->log_id;
        if(! isset($assocData['edittime'])){
            $assocData['edittime'] = time();
        }
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->appendFrom('WP_UPDATE_LOG');
        $objParameter->andWhereEqual("log_id", $log_id);
        $objParameter->setAssocData($assocData);
        $isSuccess = $this->objWidgetPoolFactory->getDataObject()->queryUpdateByParameter($objParameter);
        if(false === $isSuccess){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>UPDATE WP_UPDATE_LOG SET assocData WHERE log_id=? failed! Err Msg:' . $this->objWidgetPoolFactory->getDataObject()->getErrMessage();
            throw new WFDbDatabaseObjectException($message);
        }
        return $isSuccess;
    }
    /**
     *\brief Description
     * - setter of $this->log_id
     * @param integer $intLogId
     */
    public function setLogId($intLogId){
        $this->log_id = $intLogId;
    }
    /**
     *\brief Description
     * - This method will return PATH of /path/to/widgetPool/wpLogId
     * EX : /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool/wpLogId
     * @param integer $intLogId You can specify $intLogId to point to /path/to/widgetPool/wp$intLogId
     * @return string PATH of /path/to/widgetPool/wpLogId
     */
    protected function getPathWPLogId($intLogId = null){
        $intLogId = $this->getWPLogId($intLogId);
        $ret = $this->strWPRoot . '/wp' . $intLogId;
        return $ret;
    }
    /**
     *\brief Description
     * - This method will return $intWpLogId
     * @param integer $intLogId
     * @return integer $intLogId
     */
    protected function getWPLogId($intLogId = null){
        $ret = null === $intLogId ? $this->log_id : $intLogId;
        return $ret;
    }
    /**
     *\brief Description
     * - This method will return PATH of /path/to/widgetPool/config.php
     * EX : /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool/config.php
     * @return string PATH of /path/to/widgetPool/config.php
     */
    protected function getPathWPConfig(){
        return $this->strWPRoot . '/config.php';
    }
    /**
     *\brief Description
     * EX : /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgets_new
     * @return string PATH of /path/to/widgets_new
     */
    protected function getPathWidgetsNew(){
        $ret = $this->objFramework->getDocumentRoot() . '/repository/widgets_new';
        return $ret;
    }
    /**
     *\brief Description
     * - This is the relative path of /path/to/widgets_new from /path/to/src/inc/widget_package_manager.php
     * @return string Relative PATH of /path/to/widgets_new
     */
    protected function getPathWidgetsNewRelativePath(){
        $ret = '../repository/widgets_new';
        return $ret;
    }
    /**
     *\brief Description
     * - This is the absolute path of /path/to/widgets_new_old
     * @return string absolute PATH of /path/to/widgets_new_old
     */
    /*protected function getPathWidgetsNewOldPath(){
        $ret = $this->getPathWidgetsNew() . '_old';
        return $ret;
    }*/
    /**
     *\brief Description
     * - This is the relative path of /path/to/widgets_new_old from /path/to/src/inc/widget_package_manager.php
     * @return string Relative PATH of /path/to/widgets_new_old
     */
    /*protected function getPathWidgetsNewOldRelativePath(){
        $ret = $this->getPathWidgetsNewRelativePath() . '_old';
        return $ret;
    }*/
    /**
     *\brief Description
     * - This is the absolute path of /path/to/repository/widgetPool/wpCurrent
     * @return string absolute PATH of /path/to/repository/widgetPool/wpCurrent
     */
    protected function getWPHomePath(){
        $ret = $this->objFramework->getDocumentRoot() . '/repository/widgetPool/' . $this->getFolderCurrentWp();
        return $ret;
    }
    /**
     *\brief Description
     * - This is the relative path of /path/to/repository/widgetPool/wpCurrent from /path/to/src/inc/widget_package_manager.php
     * @return string Relative PATH of /path/to/repository/widgetPool/wpCurrent
     */
    protected function getWPHomeRelativePath(){
        $ret = '../repository/widgetPool/' . $this->getFolderCurrentWp();
        return $ret;
    }
    /**
     *\brief Description
     * - This is the absolute path of /path/to/repository/widgetPool/wpLogId
     * @return string Relative PATH of /path/to/repository/widgetPool/wpLogId
     */
    protected function getPathWPLogIdPath($intLogId = null){
        $intLogId = $this->getWPLogId($intLogId);
        $ret = $this->objFramework->getDocumentRoot() . '/repository/widgetPool/wp' . $intLogId;
        return $ret;
    }
    /**
     *\brief Description
     * - This is the relative path of /path/to/repository/widgetPool/wpLogId from /path/to/src/inc/widget_package_manager.php
     * @return string Relative PATH of /path/to/repository/widgetPool/wpLogId
     */
    protected function getPathWPLogIdRelativePath($intLogId = null){
        $intLogId = $this->getWPLogId($intLogId);
        $ret = '../repository/widgetPool/wp' . $intLogId;
        return $ret;
    }
    /**
     *\brief Description
     * - This is the absolute path of /path/to/src
     * @return string absolute PATH
     */
    protected function getDocumentRootPath(){
        $ret = $this->objFramework->getDocumentRoot();
        return $ret;
    }
    /**
     *\brief Description
     * - This is the relative path of /path/to/src from /path/to/src/inc/widget_package_manager.php
     * @return string Relative PATH of /path/to/src
     */
    protected function getDocumentRootRelativePath(){
        $ret = '..';
        return $ret;
    }
    /**
     *\brief Description
     * - This method will return folder name of  /path/to/repository/widgetPool/wpCurrent => wpCurrent
     * @return string wpCurrent from /path/to/repository/widgetPool/wpCurrent
     */
    protected function getFolderCurrentWp(){
        $strPathCurrentWp = $this->getWPHome();
        $strFolderCurrentWp = basename($strPathCurrentWp);
        return $strFolderCurrentWp;
    }
    /**
     *\brief Description
     * - This method get all currently widget_version,widget_status
     * EX:
     * $assocBeforeUpdateWidgets[widget_id]=array('widget_id'=>1,'widget_version'=>1.0,'widget_status'=>1);
     * @return array
     */
    protected function getAssocsBeforeUpdateWidgetsFromTableWidget(){
        $objParameter = $this->objFramework->getParameter();
        $objParameter->appendFrom('WIDGET');
        $objParameter->appendSelect('widget_id,widget_version,widget_status');
        $arrsWidget = $this->objFramework->getDataObject()->querySelectAllByParameter($objParameter);
        $ret = array();
        if(is_array($arrsWidget) && $arrsWidget){
            foreach($arrsWidget as $arrWidget){
                $ret[$arrWidget['widget_id']] = $arrWidget;
            }
        }
        return $ret;
    }
    /**
     *\brief Description
     * - This method get all currently widget_version,widget_status by input an $jsonBeforeUpdateWidgets
     * EX:
     * $assocBeforeUpdateWidgets[widget_id]=array('widget_id'=>1,'widget_version'=>1.0,'widget_status'=>1);
     * @return array
     */
    protected function getAssocsBeforeUpdateWidgetsByJson($jsonBeforeUpdateWidgets){
        $ret = json_decode($jsonBeforeUpdateWidgets, true);
        return $ret;
    }
    /**
     *\brief Description
     * - This method get all currently widget_version,widget_status in json format from table WIDGET
     * EX:
     * $jsonBeforeUpdateWidgets={"1":{"widget_id":1,"widget_version":"1.0","widget_status":1}}
     * @return string
     */
    protected function getJsonBeforeUpdateWidgetsFromTableWidget(){
        $assocsJsonBeforeUpdateWidgets = $this->getAssocsBeforeUpdateWidgetsFromTableWidget();
        $ret = json_encode($assocsJsonBeforeUpdateWidgets);
        return $ret;
    }
    /**
     *\brief Description
     * - This method get all currently widget_version,widget_status in assocs format from table WP_UPDATE_LOG
     * EX:
     * $jsonBeforeUpdateWidgets={"1":{"widget_id":1,"widget_version":"1.0","widget_status":1}}
     * $assocsBeforeUpdateWidgets['1'] = array("widget_id"=>'1',"widget_version"=>"1.0","widget_status"=>1)
     * @return array
     */
    public function getAssocsBeforeUpdateWidgetsFromTableWpUpdateLog(){
        $objParameter = $this->objFramework->getParameter();
        $objParameter->appendFrom('WP_UPDATE_LOG');
        $objParameter->appendSelect('before_update_widgets');
        if($this->log_id){
            $objParameter->andWhereEqual('log_id', $this->log_id);
        }else{
            $objParameter->andWhereEqual('status', '1');
            $objParameter->setOrderBy('log_id DESC');
        }
        $jsonBeforeUpdateWidgets = $this->objFramework->getDataObject()->querySelectOneByParameter($objParameter);
        $ret = array();
        if($jsonBeforeUpdateWidgets){
            $ret = $this->getAssocsBeforeUpdateWidgetsByJson($jsonBeforeUpdateWidgets);
        }
        return $ret;
    }
    /**
     *\brief Description
     * - This method get update currently widget_version,widget_status in json format to table WP_UPDATE_LOG
     * - This method get update currently wcomponent_version,wcomponent_status in json format to table WP_UPDATE_LOG
     * EX:
     * $jsonBeforeUpdateWidgets={"1":{"widget_id":1,"widget_version":"1.0","widget_status":1}}
     * $jsonBeforeUpdateWidgetComponents={"1":{"wcomponent_id":1,"wcomponent_version":"1.0","wcomponent_status":1}}
     */
    public function updateAssocsBeforeUpdateWidgetAndWidgetComponentsToTableWpUpdateLog(){
        if(! $this->log_id){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>$this->log_id is required!';
            throw new WFWidgetPoolWidgetPoolManagerException($message);
        }
        $objParameter = $this->objFramework->getParameter();
        $objParameter->appendFrom('WP_UPDATE_LOG');
        $assocData = array();
        $assocsBeforeUpdateWidgets = $this->getAssocsBeforeUpdateWidgetsFromTableWidget();
        $assocData['before_update_widgets'] = json_encode($assocsBeforeUpdateWidgets);
        $assocsBeforeUpdateWidgetComponents = $this->getAssocsBeforeUpdateWidgetComponentsFromTableWidgetComponent();
        $assocData['before_update_widget_components'] = json_encode($assocsBeforeUpdateWidgetComponents);
        $objParameter->setAssocData($assocData);
        $objParameter->andWhereEqual('log_id', $this->log_id);
        $isSuccess = $this->objFramework->getDataObject()->queryUpdateByParameter($objParameter);
        if(false === $isSuccess){
            $message = __CLASS__ . '::' . __FUNCTION__ . '()=>UPDATE WP_UPDATE_LOG SET before_update_widgets=jsonBeforeUpdateWidgets, before_update_widget_components=jsonBeforeUpdateWidgetComponents WHERE log_id=? failed! Err Msg:' . $this->objWidgetPoolFactory->getDataObject()->getErrMessage();
            throw new WFDbDatabaseObjectException($message);
        }
    }
    /************************************************
     * WIDGET_COMPONENT,WIDGET_COMPONENT_CATEGORY,WIDGET_COMPONENT_CATEGORY_MAPPING Relative API @START
     ***********************************************/
    /**
     *\brief Description
     * - Add /path/to/widget_news/widgetComponent/comNewWidgetComponent to /path/to/widgetPool/wpLogId/widgetComponent/.
     * - EX : Upgrade /path/to/widget_news/widgetComponent/comTodo which version is 2.0 to /path/to/widgetPool/wpLogId/widgetComponent/comTodo is 1.0
     */
    abstract protected function addOrUpgradeWidgetComponentFromWidgetsNew($mixProductId);
    /*protected function addOrUpgradeWidgetComponentFromWidgetsNew(){
        $arrDir = glob($this->getPathWidgetsNew() . '/widgetComponent/*', GLOB_ONLYDIR);
        if(is_array($arrDir) && $arrDir){
            foreach($arrDir as $strFullPathDir){
                $strWidgetComponentName = basename($strFullPathDir);
                $strPathWidgetComponentWPLogId = $this->getPathWPLogId() . '/widgetComponent/' . $strWidgetComponentName;
                if(false === file_exists($strPathWidgetComponentWPLogId)){
                    $this->addWidgetComponentFromWidgetsNewByWidgetComponentName($strWidgetComponentName);
                }else{
                    $this->upgradeWidgetComponentFromWidgetsNewByWidgetComponentName($strWidgetComponentName);
                }
            }
        }
    }*/
    /**
     *\brief Description
     * - Add /path/to/widget_news/widgetComponent/comNewWidgetComponent to /path/to/widgetPool/wpLogId/widgetComponent/.
     */
    protected function addWidgetComponentFromWidgetsNewByWidgetComponentName($strWidgetComponentName){
        // Step1: Copy /path/to/widgets_news/comHaveToAdd to /path/to/widgetPool/wpLogId/widgetComponent/.
        $strPathCurrentWidgetComponent = $this->getPathWidgetsNew() . '/widgetComponent/' . $strWidgetComponentName;
        $strPathDest = $this->getPathWPLogId() . '/widgetComponent/' . $strWidgetComponentName;
        $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathCurrentWidgetComponent, $strPathDest);
        // Step2: synWidgetComponentXml of comHaveToAdd
        $strPathWidgetComponent = $this->getPathWPLogId() . '/widgetComponent/' . $strWidgetComponentName;
        $this->objWidgetPoolFactory->getWidgetPoolDB()->synWidgetComponentDataToDBByWidgetComponentPath($strPathWidgetComponent);
    }
    /**
     *\brief Description
     * - EX : Upgrade /path/to/widget_news/widgetComponent/comTodo which version is 2.0 to /path/to/widgetPool/wpLogId/widgetComponent/comTodo is 1.0
     * - If widget version is compatible with Widget Framework,
     * Below is upgrade three scenerio:
     * 1)version /path/to/widgets_new/widgetComponent/comA    equal     /path/to/widgetPool/widgetComponent/comA => upgrade
     * 2)version /path/to/widgets_new/widgetComponent/comA greater than /path/to/widgetPool/widgetComponent/comA => upgrade
     * 3)version /path/to/widgets_new/widgetComponent/comA   less than  /path/to/widgetPool/widgetComponent/comA => do nothing
     */
    protected function upgradeWidgetComponentFromWidgetsNewByWidgetComponentName($strWidgetComponentName){
        $strPathWidgetComponentXMLInWidgetsNew = $this->getPathWidgetsNewRelativePath() . '/widgetComponent/' . $strWidgetComponentName . '/component.xml';
        if(! file_exists($strPathWidgetComponentXMLInWidgetsNew)){
            $strMsg = __CLASS__ . '::' . __FUNCTION__ . '()=>component.xml does not existed!';
            throw new WFWidgetPoolWidgetPoolManagerException($strMsg);
        }
        $arrDataWidgetComponentInWidgetsNew = $this->objWidgetPoolFactory->getWidgetPoolManager()->getArrDataWidgetComponentByWidgetComponentPath($strPathWidgetComponentXMLInWidgetsNew);
        $objParameter = $this->objWidgetPoolFactory->getParameter();
        $objParameter->appendFrom('WIDGET_COMPONENT');
        $objParameter->andWhereEqual('wcomponent_name', $strWidgetComponentName);
        $arrDataWidgetComponentInLocal = $this->objWidgetPoolFactory->getDataObject()->querySelectRowByParameter($objParameter);
        $floatVersionWidgetComponentInWidgetsNew = $this->objFramework->getTypeFactory()->getString()->getVersionFloatByString($arrDataWidgetComponentInWidgetsNew['wcomponent_version']);
        $floatVersionWidgetComponentInLocal = isset($arrDataWidgetComponentInLocal['wcomponent_version_float']) ? $arrDataWidgetComponentInLocal['wcomponent_version_float'] : 0;
        //$isWidgetComponentInWidgetsNewCompatibleWithWf = $this->objWidgetPoolFactory->getWidgetPoolDB()->isWidgetCompatibleWithWf($arrDataWidgetComponentInWidgetsNew);
        if(/*true === $isWidgetComponentInWidgetsNewCompatibleWithWf && */$floatVersionWidgetComponentInWidgetsNew >= $floatVersionWidgetComponentInLocal){
            // Step1: Delete /path/to/wpLogId/widgetComponent/comHaveToUpgrade
            ////$strPath = $this->getPathWPLogId() . '/widgetComponent/' . $strWidgetComponentName;
            ////$this->objWidgetPoolFactory->getIOFactory()->getFile()->rmdirRecurse($strPath);
            // Step2: Copy /path/to/widgets_news/comHaveToAdd to /path/to/widgetPool/wpLogId/widgetComponent/.
            $strPathCurrentWidgetComponent = $this->getPathWidgetsNew() . '/widgetComponent/' . $strWidgetComponentName;
            $strPathDest = $this->getPathWPLogId() . '/widgetComponent/' . $strWidgetComponentName;
            $this->objWidgetPoolFactory->getIOFactory()->getFile()->copyRecurse($strPathCurrentWidgetComponent, $strPathDest);
            // Step3: synWidgetComponentXml of comHaveToUpgrade
            $strPathWidgetComponent = $this->getPathWPLogId() . '/widgetComponent/' . $strWidgetComponentName;
            $this->objWidgetPoolFactory->getWidgetPoolDB()->synWidgetComponentDataToDBByWidgetComponentPath($strPathWidgetComponent);
        }
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidgetComponent by wcomponent_name
     *\par Variable
     * - EX: $strWidgetComponentName
     * modFlickr
     * 
     * - EX: $arrDataWidgetComponent
     * array (
     * 'wcomponent_name' => 'modFlickr',
     * 'wcomponent_version' => '1.0',
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_wf_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00'
     * )
     * @param string $strWidgetComponentName
     * @return array $arrDataWidgetComponent
     */
    public function getArrDataWidgetComponentByWidgetComponentName($strWidgetComponentName){
        $arrDataXML = $this->getArrDataWidgetComponentXMLByCondition($strWidgetComponentName);
        $ret = $this->getArrDataWidgetComponentByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidgetComponent by PATH of widgetComponent
     *\par Variable
     * - EX: $strPathWidgetComponent
     * /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool/wpLogId/comFlickr
     * 
     * - EX: $arrDataWidgetComponent
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_wf_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00'
     * )
     * @param string $strWidgetComponentName
     * @return array $arrDataWidgetComponent
     */
    public function getArrDataWidgetComponentByWidgetComponentPath($strPathWidgetComponent){
        if(false === strpos($strPathWidgetComponent, 'component.xml')){ //if not found component.xml in $strPathWidgetComponent
            $strPathWidgetComponentXml = $strPathWidgetComponent . '/component.xml';
        }else{
            $strPathWidgetComponentXml = $strPathWidgetComponent;
        }
        $arrDataXML = $this->objWidgetPoolFactory->getSimplexml($strPathWidgetComponentXml)->toArray();
        $ret = $this->getArrDataWidgetComponentByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidgetComponent by $strDom
     *\par Variable
     * - EX: $strDom
     * <?xml version="1.0" encoding="UTF-8"?>
     * <widget>
     * <wcomponent_name>comFlickr</wcomponent_name>
     * <wcomponent_version>1.0</wcomponent_version>
     * <categories>
     * <category>
     * <category_name>OSCE client</category_name>
     * <min_support_version>10.5</min_support_version>
     * </category>
     * </categories>
     * <wcomponent_status>1</wcomponent_status>
     * <wcomponent_min_support_version>2.0</wcomponent_min_support_version>
     * <wcomponent_param>0</wcomponent_param>
     * <edittime>2011-08-23 17:00:00</edittime>
     * </widget>
     * 
     * - EX: $arrDataWidgetComponent
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_support_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00'
     * )
     * @param string $strDom
     * @return array $arrDataWidgetComponent
     */
    public function getArrDataWidgetComponentByDom($strDom){
        $arrDataXML = $this->getArrDataWidgetComponentXMLByCondition(null, $strDom);
        $ret = $this->getArrDataWidgetComponentByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidgetComponent from $arrDataXML
     *\par Variable
     * - EX : $arrDataXML:
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5',
     * ),
     * ),
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_support_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00'
     * )
     * - EX: $arrDataWidgetComponent
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_support_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00'
     * )
     * @param array $arrDataXML
     * @return array $arrDataWidgetComponent
     */
    protected function getArrDataWidgetComponentByArrDataXML($arrDataXML){
        $arrData = array();
        unset($arrDataXML['categories']);
        return $arrDataXML;
    }
    /**
     *\brief Description
     * - This method will get $arrDataWidgetComponent from $arrDataXML
     *\par Variable
     * - EX : $arrData:
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5',
     * ),
     * ),
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_support_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00'
     * )
     * @param array $arrDataXML
     * @return array $arrDataWidgetComponent
     */
    public function getArrDataByWidgetComponentName($strWidgetComponentName){
        $arrData = $this->getArrDataWidgetComponentXMLByCondition($strWidgetComponentName);
        return $arrData;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetComponentCategory by $strWidgetComponentName
     *\par Variable
     * - EX : $strWidgetComponentName
     * comFlickr
     * 
     * - EX : $arrsDataWidgetComponentCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5'
     * )
     * )
     * @param string $strWidgetComponentName
     * @return array $arrsDataWidgetComponentCategory
     */
    public function getArrsDataWidgetComponentCategoryByWidgetComponentName($strWidgetComponentName){
        $arrDataXML = $this->getArrDataWidgetComponentXMLByCondition($strWidgetComponentName);
        $ret = $this->getArrsDataWidgetComponentCategoryByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetComponentCategory by $strPathWidgetComponent
     *\par Variable
     * - EX : $strPathWidgetComponent
     * /Users/jersus/htdocs/CruiseControl/projects/Widget_Framework/TMShare/AJAX-Widget/Dev/AJAX-Widgets-1.7/AJAX-Widgets/src/repository/widgetPool/wpLogId/comFlickr
     * 
     * - EX : $arrsDataWidgetComponentCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5'
     * )
     * )
     * @param string $strPathWidgetComponent
     * @return array $arrsDataWidgetComponentCategory
     */
    public function getArrsDataWidgetComponentCategoryByWidgetComponentPath($strPathWidgetComponent){
        $strPathWidgetComponentXml = $strPathWidgetComponent . '/component.xml';
        $arrDataXML = $this->objWidgetPoolFactory->getSimplexml($strPathWidgetComponentXml)->toArray();
        $ret = $this->getArrsDataWidgetComponentCategoryByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetComponentCategory by $strDom
     *\par Variable
     * - EX: $strDom
     * <?xml version="1.0" encoding="UTF-8"?>
     * <widget>
     * <wcomponent_name>comFlickr</wcomponent_name>
     * <wcomponent_version>1.0</wcomponent_version>
     * <categories>
     * <category>
     * <category_name>OSCE client</category_name>
     * <min_support_version>10.5</min_support_version>
     * </category>
     * </categories>
     * <wcomponent_status>1</wcomponent_status>
     * <wcomponent_min_support_version>2.0</wcomponent_min_support_version>
     * <wcomponent_param>0</wcomponent_param>
     * <edittime>2011-08-23 17:00:00</edittime>
     * </widget>
     * 
     * - EX : $arrsDataWidgetComponentCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5'
     * )
     * )
     * @param string $strDom
     * @return array $arrsDataWidgetComponentCategory
     */
    public function getArrsDataWidgetComponentCategoryByDom($strDom){
        $arrDataXML = $this->getArrDataWidgetComponentXMLByCondition(null, $strDom);
        $ret = $this->getArrsDataWidgetComponentCategoryByArrDataXML($arrDataXML);
        return $ret;
    }
    /**
     *\brief Description
     * - This method will get $arrsDataWidgetComponentCategory by $arrDataXML
     *\par Variable
     * - EX: $arrDataXML
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5',
     * ),
     * ),
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_support_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00',
     * )
     * 
     * - EX : $arrsDataWidgetComponentCategory
     * array (
     * 0 => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5'
     * )
     * )
     * @param array $arrDataXML
     * @return array $arrsDataWidgetComponentCategory
     */
    protected function getArrsDataWidgetComponentCategoryByArrDataXML($arrDataXML){
        $ret = array();
        //$arrDataXML['categories']['category'];
        if(! isset($arrDataXML['categories']['category'][0])){ //the category is only one
            $ret[0] = $arrDataXML['categories']['category'];
        }else{
            $ret = $arrDataXML['categories']['category'];
        }
        return $ret;
    }
    /**
     *\brief Description
     * - You can get a $objSimplexml either from $strWidgetComponentName or $strDom,
     * - This method will return the $arrDataWidgetComponentXML by call $objSimplexml->toArray()
     *\par Variable
     * - EX: $strWidgetComponentName
     * comFlickr
     * 
     * - EX: $strDom
     * <?xml version="1.0" encoding="UTF-8"?>
     * <widget>
     * <wcomponent_name>comFlickr</wcomponent_name>
     * <wcomponent_version>1.0</wcomponent_version>
     * <categories>
     * <category>
     * <category_name>OSCE client</category_name>
     * <min_support_version>10.5</min_support_version>
     * </category>
     * </categories>
     * <wcomponent_status>1</wcomponent_status>
     * <wcomponent_min_support_version>2.0</wcomponent_min_support_version>
     * <wcomponent_param>0</wcomponent_param>
     * <edittime>2011-08-23 17:00:00</edittime>
     * </widget>
     * 
     * - EX: $arrDataXML
     * array (
     * 'wcomponent_name' => 'comFlickr',
     * 'wcomponent_version' => '1.0',
     * 'categories' => 
     * array (
     * 'category' => 
     * array (
     * 'category_name' => 'OSCE client',
     * 'min_support_version' => '10.5',
     * ),
     * ),
     * 'wcomponent_status' => '1',
     * 'wcomponent_min_support_version' => '2.0',
     * 'wcomponent_param' => '',
     * 'edittime' => '2011-08-23 17:00:00',
     * )
     * 
     * @param string $strWidgetComponentName 
     * @param string $strDom
     * @return array $arrDataWidgetComponentXML
     */
    protected function getArrDataWidgetComponentXMLByCondition($strWidgetComponentName = null, $strDom = null){
        if(null !== $strWidgetComponentName){
            $strPathWidgetComponentRoot = $this->getWPHome() . '/widgetComponent';
            $strModXmlPathWidgetPool = $strPathWidgetComponentRoot . '/' . $strWidgetComponentName . '/component.xml';
            if(true === file_exists($strModXmlPathWidgetPool)){
                $objSimplexml = $this->objWidgetPoolFactory->getSimplexml($strModXmlPathWidgetPool);
            }else{
                throw new WFWidgetPoolWidgetPoolManagerException("component.xml of " . $strWidgetComponentName . " is required!");
            }
        }else{
            $objSimplexml = $this->objWidgetPoolFactory->getSimplexml($strDom);
        }
        return $objSimplexml->toArray();
    }
    /**
     *\brief Description
     * - This method get all currently wcomponent_version,wcomponent_status
     * EX:
     * $assocBeforeUpdateWidgetComponents[wcomponent_id]=array('wcomponent_id'=>1,'wcomponent_version'=>1.0,'wcomponent_status'=>1);
     * @return array
     */
    protected function getAssocsBeforeUpdateWidgetComponentsFromTableWidgetComponent(){
        $objParameter = $this->objFramework->getParameter();
        $objParameter->appendFrom('WIDGET_COMPONENT');
        $objParameter->appendSelect('wcomponent_id,wcomponent_version,wcomponent_status');
        $arrsWidgetComponent = $this->objFramework->getDataObject()->querySelectAllByParameter($objParameter);
        $ret = array();
        if(is_array($arrsWidgetComponent) && $arrsWidgetComponent){
            foreach($arrsWidgetComponent as $arrWidgetComponent){
                $ret[$arrWidgetComponent['wcomponent_id']] = $arrWidgetComponent;
            }
        }
        return $ret;
    }
/************************************************
 * WIDGET_COMPONENT,WIDGET_COMPONENT_CATEGORY,WIDGET_COMPONENT_CATEGORY_MAPPING Relative API @END
 ***********************************************/

    /**
     *\brief Description
     * - This method will update widgets widgets_update value in /path/to/repository/widgets_new_info.xml
     * - If saveXML error will throw an Exception.
     */ 
    public function updateWidgetUpdateResultToWidgetsNewInfoXml($intUpdateResult){
        $this->objWidgetsNewInfoXmlManager->updateWidgetUpdateResultToWidgetsNewInfoXml($intUpdateResult);
    }
    /**
     *\brief Description
     * - This method will update configure widgets widgets_update value in /path/to/repository/widgets_new_info.xml
     * - If saveXML error will throw an Exception.
     */ 
    public function updateConfigureWidgetUpdateResultToWidgetsNewInfoXml($intUpdateResult){
        $this->objWidgetsNewInfoXmlManager->updateConfigureWidgetUpdateResultToWidgetsNewInfoXml($intUpdateResult);
    }
    /**
     *\brief Description
     * - This method will update widgetComponents update_status value in /path/to/repository/widgets_new_info.xml
     * - If saveXML error will throw an Exception.
     */ 
    public function updateWidgetComponentUpdateResultToWidgetsNewInfoXml($intUpdateResult, $mixCategoryProductId){
        $this->objWidgetsNewInfoXmlManager->updateWidgetComponentUpdateResultToWidgetsNewInfoXml($intUpdateResult, $mixCategoryProductId);
    }
    /**
     *\brief Description
     * - Get assoc array widgetComponent update_status by product_id
     * EX : array (
          '15.2::SLF_PRODUCT_OFFICESCAN_CE' => 1,
          '15.1::SLF_PRODUCT_OFFICESCAN_CE' => 1,
        )
     */
    public function getAssocWidgetComponentUpdateStatus(){
        $ret = array();
        $assocsProductIdWithWidgetComponentFromWpCurrent = $this->getAssocsProductIdWithWidgetComponentFromWpCurrent();
        $assocsProductIdWithWidgetComponentFromWidgetsNew = $this->getAssocsProductIdWithWidgetComponentFromWidgetsNew();
        if(!is_array($assocsProductIdWithWidgetComponentFromWpCurrent)){
            $message = __CLASS__.'::'.__FUNCTION__.'()=>$assocsProductIdWithWidgetComponentFromWpCurrent is not array!';
            throw new WFWidgetInterfaceException($message);
        }
        if(!is_array($assocsProductIdWithWidgetComponentFromWidgetsNew)){
            $message = __CLASS__.'::'.__FUNCTION__.'()=>$assocsProductIdWithWidgetComponentFromWidgetsNew is not array!';
            throw new WFWidgetInterfaceException($message);
        }
        ////$strWidgetsComponentXmlBody = '';
        foreach($assocsProductIdWithWidgetComponentFromWidgetsNew as $strProductIdAndCatetoryName => $assocsWidgetComponentFromWidgetsNew){
            $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NO_NEED_UPDATE; //default is no need update
            $hasAddStatus = false; //default
            $hasUpdateStatus = false; //default
            list($product_id,$category_name) = explode('::',$strProductIdAndCatetoryName);
            //<product_type id="15.2" name="OfficeScan Server">
            ////$strWidgetsComponentXmlBody .= '<product_type id="'.$product_id.'" name="'.$category_name.'">';
            foreach($assocsWidgetComponentFromWidgetsNew as $wcompnent_name => $assocWidgetComponentFromWidgetsNew){
                //var_dump($product_id,$wcompnent_name,$assocWidgetComponentFromWidgetsNew);exit();
                $assocWidgetComponentFromWpCurrent = isset($assocsProductIdWithWidgetComponentFromWpCurrent[$strProductIdAndCatetoryName][$wcompnent_name]) ? $assocsProductIdWithWidgetComponentFromWpCurrent[$strProductIdAndCatetoryName][$wcompnent_name] : array();
                //var_dump($assocWidgetComponentFromWpCurrent);exit();
                if(!isset($assocWidgetComponentFromWpCurrent['wcomponent_name'])){ //if widgetComponent exist in widgets_new && not exist wpCurrent
                    $hasAddStatus = true;
                    if(true === $hasUpdateStatus){ //if $hasAddStatus=true && $hasUpdateStatus=true ==> update_status=need to update
                        $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_UPDATE;
                        break;
                    }else{
                        $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_ENABLE;
                    }
                }else{  //if widget exist in both widgets_new && wpCurrent
                    $hasUpdateStatus = true;
                    $floatVersionWidgetFromWidgetsNew = $this->objFramework->getTypeFactory()->getString()->getVersionFloatByString($assocWidgetComponentFromWidgetsNew['wcomponent_version']);
                    $floatVersionWidgetFromWpCurrent = $this->objFramework->getTypeFactory()->getString()->getVersionFloatByString($assocWidgetComponentFromWpCurrent['wcomponent_version']);
                    if($floatVersionWidgetFromWidgetsNew > $floatVersionWidgetFromWpCurrent){
                        $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_UPDATE;
                        break;
                    }
                }
            }
            $ret[$strProductIdAndCatetoryName] = $intUpdateStatus;
        }
        return $ret;
    }
    /**
     *\par Variable
     * - EX: $assocsWidgetFromWidgetsNew
     * array (
          'modSample' => 
          array (
            'widget_name' => 'modSample',
            'modname' => 'modSample',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modSample2' => 
          array (
            'widget_name' => 'modSample2',
            'modname' => 'modSample2',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          )
	)
     */
    public function getAssocsWidgetFromWidgetsNew(){
        $arrWidgetType = $this->objFramework->getConfigFactory()->getOpt()->getWidgetType();
        $assocsWidgetFromWidgetsNew = $this->getAssocsWidgetAllFromWidgetsNewByArrWidgetType($arrWidgetType);
        return $assocsWidgetFromWidgetsNew;
    }
    /**
     *\par Variable
     * - EX : $assocsConfigureWidgetFromWidgetsNew
     *array (
          'modPolicyList' => 
          array (
            'widget_name' => 'modPolicyList',
            'modname' => 'modPolicyList',
            'widget_version' => '1.0',
            'widget_type' => '3',
            'widget_min_wf_version' => '3.0',
          ),
          'modScopeList' => 
          array (
            'widget_name' => 'modScopeList',
            'modname' => 'modScopeList',
            'widget_version' => '1.0',
            'widget_type' => '3',
            'widget_min_wf_version' => '3.0',
          ),
        )
     */
    public function getAssocsConfigureWidgetFromWidgetsNew(){
        $arrWidgetType = $this->objFramework->getConfigFactory()->getOpt()->getConfigureWidgetType();
        $assocsConfigureWidgetFromWidgetsNew = $this->getAssocsWidgetAllFromWidgetsNewByArrWidgetType($arrWidgetType);
        return $assocsConfigureWidgetFromWidgetsNew;
    }
    /**
     *\par Variable
     * - EX : $assocsWidgetAllFromWidgetsNew
     *array (
     	  'modSample' => 
          array (
            'widget_name' => 'modSample',
            'modname' => 'modSample',
            'widget_version' => '2.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modSearch' => 
          array (
            'widget_name' => 'modSearch',
            'modname' => 'modSearch',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modTodo' => 
          array (
            'widget_name' => 'modTodo',
            'modname' => 'modTodo',
            'widget_version' => '2.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modWeather' => 
          array (
            'widget_name' => 'modWeather',
            'modname' => 'modWeather',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modPolicyList' => 
          array (
            'widget_name' => 'modPolicyList',
            'modname' => 'modPolicyList',
            'widget_version' => '1.0',
            'widget_type' => '3',
            'widget_min_wf_version' => '3.0',
          ),
          'modScopeList' => 
          array (
            'widget_name' => 'modScopeList',
            'modname' => 'modScopeList',
            'widget_version' => '1.0',
            'widget_type' => '3',
            'widget_min_wf_version' => '3.0',
          ),
        )
     */
    public function getAssocsWidgetAllFromWidgetsNew(){
        $assocsWidgetAllFromWidgetsNew = $this->getAssocsWidgetAllFromWidgetsNewByArrWidgetType();
        return $assocsWidgetAllFromWidgetsNew;
    }
    /**
     *\par Variable
     * - EX : $assocsConfigureWidgetFromWidgetsNew
     *array (
          'modPolicyList' => 
          array (
            'widget_name' => 'modPolicyList',
            'modname' => 'modPolicyList',
            'widget_version' => '1.0',
            'widget_type' => '3',
            'widget_min_wf_version' => '3.0',
          ),
          'modScopeList' => 
          array (
            'widget_name' => 'modScopeList',
            'modname' => 'modScopeList',
            'widget_version' => '1.0',
            'widget_type' => '3',
            'widget_min_wf_version' => '3.0',
          ),
        )
     */
    protected function getAssocsWidgetAllFromWidgetsNewByArrWidgetType($arrWidgetType = null){
        $arrWidgetType = null !== $arrWidgetType ? $arrWidgetType : $this->objFramework->getConfigFactory()->getOpt()->getWidgetAllType();
        $assocsWidgetTypeWithWidgetAllFromWidgetsNew = $this->getAssocsWidgetTypeWithWidgetAllFromWidgetsNew();
        
        $assocsConfigureWidgetFromWidgetsNew = array();
        
        foreach($arrWidgetType as $intWidgetType){
            // retrieve widget from $assocsWidgetTypeWithWidgetAllFromWidgetsNew
            if(isset($assocsWidgetTypeWithWidgetAllFromWidgetsNew[$intWidgetType]) && $assocsWidgetTypeWithWidgetAllFromWidgetsNew[$intWidgetType]){
                $assocsConfigureWidgetFromWidgetsNew = array_merge($assocsConfigureWidgetFromWidgetsNew,$assocsWidgetTypeWithWidgetAllFromWidgetsNew[$intWidgetType]);
            }
        }
        //var_export($assocsConfigureWidgetFromWidgetsNew);
        return $assocsConfigureWidgetFromWidgetsNew;
    }
    /**
     *\brief Description
     *\par Variable
     * - EX: $assocsWidgetFromWpCurrent
     * array (
          'modSample' => 
          array (
            'widget_name' => 'modSample',
            'modname' => 'modSample',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
        )array (
          'modSample' => 
          array (
            'widget_name' => 'modSample',
            'modname' => 'modSample',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
        )
     */
    public function getAssocsWidgetFromWpCurrent(){
        $arrWidgetType = $this->objFramework->getConfigFactory()->getOpt()->getWidgetType();
        $assocsWidgetFromWpCurrent = $this->getAssocsWidgetAllFromWpCurrentByArrWidgetType($arrWidgetType);
        return $assocsWidgetFromWpCurrent;
    }
    public function getAssocsConfigureWidgetFromWpCurrent(){
        $arrWidgetType = $this->objFramework->getConfigFactory()->getOpt()->getConfigureWidgetType();
        $assocsWidgetFromWpCurrent = $this->getAssocsWidgetAllFromWpCurrentByArrWidgetType($arrWidgetType);
        return $assocsWidgetFromWpCurrent;
    }
    /**
     *\par Variable
     * - EX : $ssocsWidgetAllFromWpCurrent
     * array (
          'modSample' => 
          array (
            'widget_name' => 'modSample',
            'modname' => 'modSample',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modSample2' => 
          array (
            'widget_name' => 'modSample2',
            'modname' => 'modSample2',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modSample3' => 
          array (
            'widget_name' => 'modSample3',
            'modname' => 'modSample3',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modZMultiple' => 
          array (
            'widget_name' => 'modZMultiple',
            'modname' => 'modZMultiple',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
        )
     */
    public function getAssocsWidgetAllFromWpCurrent(){
        $assocsWidgetFromWpCurrent = $this->getAssocsWidgetAllFromWpCurrentByArrWidgetType();
        var_export($assocsWidgetFromWpCurrent);
        return $assocsWidgetFromWpCurrent;
    }
    /**
     *\par Variable 
     * - EX : $assocsWidgetAllFromWpCurrentByArrWidgetType
     * array (
          'modSample' => 
          array (
            'widget_name' => 'modSample',
            'modname' => 'modSample',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modSample2' => 
          array (
            'widget_name' => 'modSample2',
            'modname' => 'modSample2',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modSample3' => 
          array (
            'widget_name' => 'modSample3',
            'modname' => 'modSample3',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
          'modZMultiple' => 
          array (
            'widget_name' => 'modZMultiple',
            'modname' => 'modZMultiple',
            'widget_version' => '1.0',
            'widget_type' => '1',
            'widget_min_wf_version' => '2.0',
          ),
        )
     */
    protected function getAssocsWidgetAllFromWpCurrentByArrWidgetType($arrWidgetType = null){
        $arrWidgetType = null !== $arrWidgetType ? $arrWidgetType : $this->objFramework->getConfigFactory()->getOpt()->getWidgetAllType();
        $assocsWidgetTypeWithWidgetAllFromWpCurrent = $this->getAssocsWidgetTypeWithWidgetAllFromWpCurrent();
        
        $assocsWidgetFromWpCurrent = array();
        
        foreach($arrWidgetType as $intWidgetType){
            // retrieve widget from $assocsWidgetTypeWithWidgetAllFromWpCurrent
            if(isset($assocsWidgetTypeWithWidgetAllFromWpCurrent[$intWidgetType]) && $assocsWidgetTypeWithWidgetAllFromWpCurrent[$intWidgetType]){
                $assocsWidgetFromWpCurrent = array_merge($assocsWidgetFromWpCurrent,$assocsWidgetTypeWithWidgetAllFromWpCurrent[$intWidgetType]);
            }
        }
        return $assocsWidgetFromWpCurrent;
    }
    /**
     *\brief Description
     * @return integer update_status of widget, 0=no need update,1=need enable,2=need update,3=update success,4=update failed
     */
    public function getWidgetUpdateStatus(){
        $arrWidgetType = $this->objFramework->getConfigFactory()->getOpt()->getWidgetType();
        $ret = $this->getWidgetOrConfigureWidgetUpdateStatus($arrWidgetType);
        return $ret;
    }
    /**
     *\brief Description
     * @return integer update_status of configure widget, 0=no need update,1=need enable,2=need update,3=update success,4=update failed
     */
    public function getConfigureWidgetUpdateStatus(){
        $arrWidgetType = $this->objFramework->getConfigFactory()->getOpt()->getConfigureWidgetType();
        $ret = $this->getWidgetOrConfigureWidgetUpdateStatus($arrWidgetType);
        return $ret;
    }
    /**
     * @param array $arrWidgetType array('3') equals configure widget and array('0','1','2') equals widget
     */
    protected function getWidgetOrConfigureWidgetUpdateStatus($arrWidgetType){
        $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NO_NEED_UPDATE; //default is no need update
        if(!(is_array($arrWidgetType) && $arrWidgetType)){
            $message = __CLASS__.'::'.__FUNCTION__.'()=>Parameter $arrWidgetType is empty!';
            throw new WFWidgetInterfaceException($message);
        }
        $assocsWidgetFromWpCurrent = $this->getAssocsWidgetAllFromWpCurrentByArrWidgetType($arrWidgetType);
        $assocsWidgetFromWidgetsNew = $this->getAssocsWidgetAllFromWidgetsNewByArrWidgetType($arrWidgetType);
        $intWidgetFromWpCurrent = count($assocsWidgetFromWpCurrent);
        $intWidgetFromWidgetsNew = count($assocsWidgetFromWidgetsNew);
        //If number of widget in widgets_new > number of widget in wpCurrent = need to add
        if($intWidgetFromWidgetsNew > 0){
            if($intWidgetFromWidgetsNew > $intWidgetFromWpCurrent){
                $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_UPDATE;
            }else{
                foreach($assocsWidgetFromWidgetsNew as $widget_name => $assocWidgetFromWidgetsNew){
                    if(!isset($assocsWidgetFromWpCurrent[$widget_name])){ //if widget exist in widgets_new && not exist wpCurrent
                        $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_UPDATE;
                        break;
                    }else{  //if widget exist in both widgets_new && wpCurrent
                        $floatVersionWidgetFromWidgetsNew = $this->objFramework->getTypeFactory()->getString()->getVersionFloatByString($assocWidgetFromWidgetsNew['widget_version']);
                        $floatVersionWidgetFromWpCurrent = $this->objFramework->getTypeFactory()->getString()->getVersionFloatByString($assocsWidgetFromWpCurrent[$widget_name]['widget_version']);
                        if($floatVersionWidgetFromWidgetsNew > $floatVersionWidgetFromWpCurrent){
                            $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_UPDATE;
                            break;
                        }
                    }
                }
            }
        }
        return $intUpdateStatus;
    }
    /**
     *\brief Description
     * - Check is need to analyze widgets_new_info.xml or not
     */
    public function isNeedToAnalyzeWidgetsNewInfo(){
        $ret = false;
        $strPathWidgetsNew = $this->objFramework->getDocumentRoot().'/repository/widgets_new';
        $strPathWidgetsNewInfo = $this->objFramework->getDocumentRoot().'/repository/widgets_new_info.xml';
        if(true === file_exists($strPathWidgetsNew)){
            if(false === file_exists($strPathWidgetsNewInfo)){
                $ret = true;
            }
        }
        return $ret;
    }
    /**
     *\brief Description
     * Get update_status from /path/to/repository/widgets_new_info.xml.
     * - If widget => get widget update_status
     * - If configure widget => get configure widget update_status
     * - If widget component => get widget component update_status
     */
    public function getUpdateStatusFromWidgetsNewInfoXml(){
        $strFuncName = 'get'.$this->objFramework->getTypeFactory()->getString()->getUpperCamelCase($this->strUpdateType).'UpdateStatusFromWidgetsNewInfoXml';
        $ret = $this->objWidgetsNewInfoXmlManager->$strFuncName();
        return $ret;
    }
    /**
     *\brief Description
     * Get update_status after analyze update_status and update_result.
     */
    protected function getUpdateStatusByCondition($intUpdateStatus,$intUpdateResult){
        if($intUpdateStatus == WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_UPDATE || $intUpdateStatus == WFWidgetPoolOpt::WP_UPDATE_STATUS_NEED_ENABLE){
            if($intUpdateResult == WFWidgetPoolOpt::WP_UPDATE_RESULT_UPDATE_SUCCESS){
                $intUpdateStatus = WFWidgetPoolOpt::WP_UPDATE_STATUS_NO_NEED_UPDATE;
            }
        }
        return $intUpdateStatus;
    }
    /**
     *\brief Description
     * Get is need to update_status after analyze configure_widget_update_status and configure_widget_update_result.
     */
    protected function getWidgetUpdateStatusByUpdateStatusAndUpdateResult(){
        $intWidgetUpdateStatusFromWidgetsNewInfoXml = $this->objWidgetsNewInfoXmlManager->getWidgetUpdateStatusFromWidgetsNewInfoXml();
        $intWidgetUpdateResultFromWidgetsNewInfoXml = $this->objWidgetsNewInfoXmlManager->getWidgetUpdateResultFromWidgetsNewInfoXml();
        $intUpdateStatus = $this->getUpdateStatusByCondition($intWidgetUpdateStatusFromWidgetsNewInfoXml, $intWidgetUpdateResultFromWidgetsNewInfoXml);
        return $intUpdateStatus;
    }
    /**
     *\brief Description
     * Check is configure widget need to update by analyze configure_widget_update_status and configure_widget_update_result. If need return true else return false
     */
    protected function getConfigureWidgetUpdateStatusByUpdateStatusAndUpdateResult(){
        $intConfigureWidgetUpdateStatusFromWidgetsNewInfoXml = $this->objWidgetsNewInfoXmlManager->getConfigureWidgetUpdateStatusFromWidgetsNewInfoXml();
        $intConfigureWidgetUpdateResultFromWidgetsNewInfoXml = $this->objWidgetsNewInfoXmlManager->getConfigureWidgetUpdateResultFromWidgetsNewInfoXml();
        $intUpdateStatus = $this->getUpdateStatusByCondition($intConfigureWidgetUpdateStatusFromWidgetsNewInfoXml, $intConfigureWidgetUpdateResultFromWidgetsNewInfoXml);
        return $intUpdateStatus;
    }
    /**
     *\brief Description
     * Check if the pool update package has been downloaded (only for TMCM)
     */
    public function isSCMUpdate($arrCookie = null){
    	$checkResult = array();
    	
    	if( file_exists($GLOBALS['scm_path'])){	//check SCMUpdate folders
			$checkResult["progress"] = 1;
		}else if( file_exists($this->getPathWidgetsNew())){ //check widgets_new folder
			$checkResult["progress"] = 2;
		}else{ // no pool update
			$checkResult["progress"] = 0;
		}
    
    	if( $checkResult["progress"] > 0 ){
    		$objHttpTalk = $this->objFramework->getProxyFactory()->getHttpTalk();
    			
    		// Step 1: Set URL to proxy_controller.php
    		$objConfig = $this->objConfig;
    		$URL = $objConfig->getHttpProtocal().$objConfig->getHttpHost()."/WebApp/widget/proxy_controller.php";
    		$objHttpTalk->setURL($URL);
    			
    		// Step 2: prepare parameter needed
    		$objHttpTalk->setCGI_all( array( 'module'=> 'modSCloud', 'taskAction'=> 'CheckSCMVersion', 'hotFixPath'=> $checkResult["progress"]) );
    			
    		if(null !== $arrCookie){
    			// Step 3: set COOKIE for authentication
    			$objHttpTalk->setCookies($arrCookie);
    		}
    			
    		// send request to sCloudService via soap
    		$objHttpTalk->setMethod_POST();
    		if( $objHttpTalk->Send() !== FALSE ){
    			$jsonResult = $objHttpTalk->getBody();
    			$this->objLogger->info('[SCM version check]: ' . $jsonResult);
    			$jsonResult = json_decode($jsonResult, true);
    			if( $jsonResult["DocumentElement"]["Result"] == 0 ){
    				$checkResult["version_check_result"] = $jsonResult["DocumentElement"]["Data"]["Result"];
    				$checkResult["version_error_code"] = $jsonResult["DocumentElement"]["Data"]["ErrorCode"];
    				$checkResult["patch_min"] = $jsonResult["DocumentElement"]["Data"]["PatchMin"];
    				$this->setWidgetsAndWCUsUpdateFlag($checkResult);
    				return $checkResult;
    			}
    		}
    	}
    
    	$checkResult["version_check_result"] = -1;
    	$checkResult["version_error_code"] = 0;
    	$this->setWidgetsAndWCUsUpdateFlag($checkResult);
    	
    	return $checkResult;
    }	
    /**
     *\brief Description
     * Set flags for widgets and WCU are needed to be upgraded. 
     */
    private function setWidgetsAndWCUsUpdateFlag(&$checkResult){
    	if( $checkResult["progress"] <= 1 || $checkResult["version_check_result"] == -1 ){
    		$checkResult["is_new_widgets_update"] = false;
    		$checkResult["is_new_wcu_update"] = false;
    	}else{
    		$checkResult["is_new_widgets_update"] = WF::getWidgetPoolFactory()->getWidgetPoolManager('widget')->isWidgetUpdate();
    		$checkResult["is_new_wcu_update"] = WF::getWidgetPoolFactory()->getWidgetPoolManager('configure_widget_and_widget_component')->isConfigureWidgetAndWidgetComponentUpdate();
    	}	
    }    
    /**
     *\brief Description
     * Check is widget need to update. If need return true else return false
     */
    public function isWidgetUpdate(){
        $this->objFramework->getWidgetFactory()->getInterface()->analyzeWidgetsNewInfo();
        $intWidgetUpdateStatusByUpdateStatusAndUpdateResult = $this->getWidgetUpdateStatusByUpdateStatusAndUpdateResult();
        return $intWidgetUpdateStatusByUpdateStatusAndUpdateResult ? true : false;
    }
    /**
     *\brief Description
     * Check is configure_widget_and_widget_component need to update. If need return true else return false
     */
    public function isConfigureWidgetAndWidgetComponentUpdate(){
        $intConfigureWidgetUpdateStatusByUpdateStatusAndUpdateResult = $this->getConfigureWidgetUpdateStatusByUpdateStatusAndUpdateResult();
        $ret = $intConfigureWidgetUpdateStatusByUpdateStatusAndUpdateResult ? true : false;
        if(false === $ret){
            $arrsWidgetComponentUpdateStatusFromWidgetsNewInfoXml = $this->objWidgetsNewInfoXmlManager->getArrsWidgetComponentUpdateStatusFromWidgetsNewInfoXml();
            if(is_array($arrsWidgetComponentUpdateStatusFromWidgetsNewInfoXml) && $arrsWidgetComponentUpdateStatusFromWidgetsNewInfoXml){
                foreach($arrsWidgetComponentUpdateStatusFromWidgetsNewInfoXml as $assocWidgetComponentUpdateStatusFromWidgetsNewInfoXml){
                    $intUpdateStatus = $this->getUpdateStatusByCondition($assocWidgetComponentUpdateStatusFromWidgetsNewInfoXml['update_status'],$assocWidgetComponentUpdateStatusFromWidgetsNewInfoXml['update_result']);
                    $isUpdate = $intUpdateStatus ? true : false;
                    if(true === $isUpdate){
                        $ret = true;
                        break;
                    }
                }
            }
        }
        return $ret;
    }
    abstract protected function updateSuccessResultToWidgetsNewInfoXml($mixProductId);
    abstract protected function updateFailedResultToWidgetsNewInfoXml($mixProductId);
}
